<commit_before>package adapt

// Config represents a configuration of the algorithm.
type Config struct {
	// The refinement rate of the algorithm. The parameter specifies the
	// fraction of the nodes queued for refinement to be taken from the queue at
	// each iteration.
	Rate float64 // ⊆ (0, 1]

	// The minimal level of interpolation. The nodes that belong to lower levels
	// are unconditionally included in the surrogate.
	MinLevel uint

	// The maximal level of interpolation. The nodes that belong to this level
	// are never refined.
	MaxLevel uint

	// A flag to enable grid balancing. If it is set to true, additional nodes
	// are added at each iteration to balance the underlying grid. Note that
	// Target.Score should not reject any nodes in this case.
	Balance bool

	// The number of concurrent workers. The evaluation of the target function
	// and the surrogate itself is distributed among this many goroutines.
	Workers uint
}

// NewConfig returns a new configuration with default values.
func NewConfig() *Config {
	return &Config{
		Rate:     1,
		MinLevel: 1,
		MaxLevel: 9,
	}
}
<commit_msg>Adjust the description of Config<commit_after>package adapt

// Config represents a configuration of the algorithm.
type Config struct {
	// The refinement rate of the algorithm. The parameter specifies the
	// fraction of the nodes queued for refinement to be taken from the queue at
	// each iteration.
	Rate float64 // ⊆ (0, 1]

	// The minimum level of interpolation. The nodes that belong to lower levels
	// are unconditionally included in the surrogate.
	MinLevel uint

	// The maximum level of interpolation. The nodes that belong to this level
	// are never refined.
	MaxLevel uint

	// A flag to enable grid balancing. If it is set to true, additional nodes
	// are added at each iteration to balance the underlying grid. Note that
	// Target.Score should not reject any nodes in this case.
	Balance bool

	// The number of concurrent workers. The evaluation of the target function
	// and the surrogate itself is distributed among this many goroutines.
	Workers uint
}

// NewConfig returns a new configuration with default values.
func NewConfig() *Config {
	return &Config{
		Rate:     1,
		MinLevel: 1,
		MaxLevel: 9,
	}
}
<|endoftext|>


<commit_before>package oz

import (
	"encoding/json"
	"io/ioutil"
	"os"
)

type Config struct {
	ProfileDir      string   `json:"profile_dir" desc:"Directory containing the sandbox profiles"`
	ShellPath       string   `json:"shell_path" desc:"Path of the shell used when entering a sandbox"`
	PrefixPath      string   `json:"prefix_path" desc:"Prefix path containing the oz executables"`
	EtcPrefix       string   `json:"etc_prefix" desc:"Prefix for configuration files"`
	SandboxPath     string   `json:"sandbox_path" desc:"Path of the sandboxes base"`
	OpenVPNRunPath  string   `json:"openvpn_run_path" desc: "Path for OpenVPN run state"`
	OpenVPNConfDir  string   `json:"openvpn_conf_dir" desc: "Path for OpenVPN conf files"`
	OpenVPNGroup    string   `json:"openvpn_group" desc: "GID for OpenVPN process"`
	RouteTableBase  int      `json:"route_table_base" desc: "Base for routing table"`
	BridgeMACAddr   string   `json:"bridge_mac" desc:"MAC Address of the bridge interface"`
	DivertSuffix    string   `json:"divert_suffix" desc:"Suffix using for dpkg-divert of application executables, can be left empty when using a divert path"`
	DivertPath      bool     `json:"divert_path" desc:"Whether the diverted executable should be moved out of the path"`
	NMIgnoreFile    string   `json:"nm_ignore_file" desc:"Path to the NetworkManager ignore config file, disables the warning if empty"`
	UseFullDev      bool     `json:"use_full_dev" desc:"Give sandboxes full access to devices instead of a restricted set"`
	AllowRootShell  bool     `json:"allow_root_shell" desc:"Allow entering a sandbox shell as root"`
	LogXpra         bool     `json:"log_xpra" desc:"Log output of Xpra"`
	EnvironmentVars []string `json:"environment_vars" desc:"Default environment variables passed to sandboxes"`
	DefaultGroups   []string `json:"default_groups" desc:"List of default group names that can be used inside the sandbox"`
}

const OzVersion = "0.0.1"
const DefaultConfigPath = "/etc/oz/oz.conf"

func NewDefaultConfig() *Config {
	return &Config{
		ProfileDir:     "/var/lib/oz/cells.d",
		ShellPath:      "/bin/bash",
		PrefixPath:     "/usr/local",
		EtcPrefix:      "/etc/oz",
		SandboxPath:    "/srv/oz",
		OpenVPNRunPath: "/var/run/openvpn",
		OpenVPNConfDir: "/var/lib/oz/openvpn",
		OpenVPNGroup:   "oz-openvpn",
		RouteTableBase: 8000,
		DivertPath:     true,
		NMIgnoreFile:   "/etc/NetworkManager/conf.d/oz.conf",
		BridgeMACAddr:  "6A:A8:2E:56:E8:9C",
		DivertSuffix:   "",
		UseFullDev:     false,
		AllowRootShell: false,
		LogXpra:        true,
		EnvironmentVars: []string{
			"USER", "USERNAME", "LOGNAME",
			"LANG", "LANGUAGE", "_", "TZ=UTC",
			"XDG_SESSION_TYPE", "XDG_RUNTIME_DIR", "XDG_DATA_DIRS",
			"XDG_SEAT", "XDG_SESSION_TYPE", "XDG_SESSION_ID",
		},
		DefaultGroups: []string{
			"audio", "video",
		},
	}
}

func LoadConfig(cpath string) (*Config, error) {
	if _, err := os.Stat(cpath); os.IsNotExist(err) {
		return nil, err
	}
	if err := checkConfigPermissions(cpath); err != nil {
		return nil, err
	}

	bs, err := ioutil.ReadFile(cpath)
	if err != nil {
		return nil, err
	}
	c := NewDefaultConfig()
	if err := json.Unmarshal(bs, c); err != nil {
		return nil, err
	}

	if c.DivertSuffix == "" && c.DivertPath == false {
		c.DivertSuffix = "unsafe"
	}

	return c, nil
}
<commit_msg>Removed unused BridgeMACAddr...<commit_after>package oz

import (
	"encoding/json"
	"io/ioutil"
	"os"
)

type Config struct {
	ProfileDir      string   `json:"profile_dir" desc:"Directory containing the sandbox profiles"`
	ShellPath       string   `json:"shell_path" desc:"Path of the shell used when entering a sandbox"`
	PrefixPath      string   `json:"prefix_path" desc:"Prefix path containing the oz executables"`
	EtcPrefix       string   `json:"etc_prefix" desc:"Prefix for configuration files"`
	SandboxPath     string   `json:"sandbox_path" desc:"Path of the sandboxes base"`
	OpenVPNRunPath  string   `json:"openvpn_run_path" desc: "Path for OpenVPN run state"`
	OpenVPNConfDir  string   `json:"openvpn_conf_dir" desc: "Path for OpenVPN conf files"`
	OpenVPNGroup    string   `json:"openvpn_group" desc: "GID for OpenVPN process"`
	RouteTableBase  int      `json:"route_table_base" desc: "Base for routing table"`
	DivertSuffix    string   `json:"divert_suffix" desc:"Suffix using for dpkg-divert of application executables, can be left empty when using a divert path"`
	DivertPath      bool     `json:"divert_path" desc:"Whether the diverted executable should be moved out of the path"`
	NMIgnoreFile    string   `json:"nm_ignore_file" desc:"Path to the NetworkManager ignore config file, disables the warning if empty"`
	UseFullDev      bool     `json:"use_full_dev" desc:"Give sandboxes full access to devices instead of a restricted set"`
	AllowRootShell  bool     `json:"allow_root_shell" desc:"Allow entering a sandbox shell as root"`
	LogXpra         bool     `json:"log_xpra" desc:"Log output of Xpra"`
	EnvironmentVars []string `json:"environment_vars" desc:"Default environment variables passed to sandboxes"`
	DefaultGroups   []string `json:"default_groups" desc:"List of default group names that can be used inside the sandbox"`
}

const OzVersion = "0.0.1"
const DefaultConfigPath = "/etc/oz/oz.conf"

func NewDefaultConfig() *Config {
	return &Config{
		ProfileDir:     "/var/lib/oz/cells.d",
		ShellPath:      "/bin/bash",
		PrefixPath:     "/usr/local",
		EtcPrefix:      "/etc/oz",
		SandboxPath:    "/srv/oz",
		OpenVPNRunPath: "/var/run/openvpn",
		OpenVPNConfDir: "/var/lib/oz/openvpn",
		OpenVPNGroup:   "oz-openvpn",
		RouteTableBase: 8000,
		DivertPath:     true,
		NMIgnoreFile:   "/etc/NetworkManager/conf.d/oz.conf",
		DivertSuffix:   "",
		UseFullDev:     false,
		AllowRootShell: false,
		LogXpra:        true,
		EnvironmentVars: []string{
			"USER", "USERNAME", "LOGNAME",
			"LANG", "LANGUAGE", "_", "TZ=UTC",
			"XDG_SESSION_TYPE", "XDG_RUNTIME_DIR", "XDG_DATA_DIRS",
			"XDG_SEAT", "XDG_SESSION_TYPE", "XDG_SESSION_ID",
		},
		DefaultGroups: []string{
			"audio", "video",
		},
	}
}

func LoadConfig(cpath string) (*Config, error) {
	if _, err := os.Stat(cpath); os.IsNotExist(err) {
		return nil, err
	}
	if err := checkConfigPermissions(cpath); err != nil {
		return nil, err
	}

	bs, err := ioutil.ReadFile(cpath)
	if err != nil {
		return nil, err
	}
	c := NewDefaultConfig()
	if err := json.Unmarshal(bs, c); err != nil {
		return nil, err
	}

	if c.DivertSuffix == "" && c.DivertPath == false {
		c.DivertSuffix = "unsafe"
	}

	return c, nil
}
<|endoftext|>


<commit_before>package main

import "github.com/BurntSushi/toml"

type Config struct {
	App  App  `toml:"application"`
	Deps Deps `toml:"dependencies"`
}

type App struct {
	Name    string
	Version string
	Authors []string
}

type Deps map[string]string

func loadConfig() (*Config, error) {
	var c Config
	_, err := toml.DecodeFile(setting.ConfigFile, &c)
	if err != nil {
		return nil, err
	}

	return &c, nil
}
<commit_msg>Rename `App` to `ConfigApp`, `Deps` to `ConfigDeps`<commit_after>package main

import "github.com/BurntSushi/toml"

type Config struct {
	App  ConfigApp  `toml:"application"`
	Deps ConfigDeps `toml:"dependencies"`
}

type ConfigApp struct {
	Name    string
	Version string
	Authors []string
}

type ConfigDeps map[string]string

func loadConfig() (*Config, error) {
	var c Config
	_, err := toml.DecodeFile(setting.ConfigFile, &c)
	if err != nil {
		return nil, err
	}

	return &c, nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	consulapi "github.com/hashicorp/consul/api"
	"time"
)

type ConsulClient struct {
	client *consulapi.Client
}

func NewConsulClient() (ConsulClient, error) {
	client, err := consulapi.NewClient(consulapi.DefaultConfig())
	if err != nil {
		return ConsulClient{}, err
	}
	return ConsulClient{client: client}, nil
}

type ConsulAgent struct {
	agent *consulapi.Agent
}

func (r *ConsulClient) NewConsulAgent() ConsulAgent {
	agent := r.client.Agent()
	return ConsulAgent{agent: agent}
}

type Member struct {
	Name string
	IP   string
	Port uint16
}

type Members []Member

func buildMember(name string, ip string, port uint16) Member {
	return Member{Name: name, IP: ip, Port: port}
}

func (r *ConsulAgent) members() Members {
	list := Members{}
	use_wan := false
	members, _ := r.agent.Members(use_wan)
	for _, member := range members {
		list = append(list, buildMember(member.Name, member.Addr, member.Port))
	}
	return list
}

// type AgentServiceRegistration struct {
//	ID      string   `json:",omitempty"`
//	Name    string   `json:",omitempty"`
//	Tags    []string `json:",omitempty"`
//	Port    int      `json:",omitempty"`
//	Address string   `json:",omitempty"`
//	Check   *AgentServiceCheck
//	Checks  AgentServiceChecks
// }

func buildService(id string, name string, port int, ip string) consulapi.AgentServiceRegistration {
	return consulapi.AgentServiceRegistration{ID: id, Name: name, Port: port, Address: ip}
}

func (r *ConsulAgent) registerService(id string, name string, port int, ip string) error {
	srv := buildService(id, name, port, ip)
	if err := r.agent.ServiceRegister(&srv); err != nil {
		return err
	}
	return nil
}

func (r *ConsulAgent) deregisterService(id string) error {
	if err := r.agent.ServiceDeregister(id); err != nil {
		return err
	}
	return nil
}

func main() {
	client, _ := NewConsulClient()
	agent := client.NewConsulAgent()

	fmt.Println(agent.members())

	agent.registerService("docker_id_here", "srv-search", 1234, "127.0.0.1")
	time.Sleep(20 * time.Second)

	agent.deregisterService("docker_id_here")
}
<commit_msg>add services() to consul<commit_after>package main

import (
	"fmt"
	consulapi "github.com/hashicorp/consul/api"
	"time"
)

type ConsulClient struct {
	client *consulapi.Client
}

func NewConsulClient() (ConsulClient, error) {
	client, err := consulapi.NewClient(consulapi.DefaultConfig())
	if err != nil {
		return ConsulClient{}, err
	}
	return ConsulClient{client: client}, nil
}

type ConsulAgent struct {
	agent *consulapi.Agent
}

func (r *ConsulClient) NewConsulAgent() ConsulAgent {
	agent := r.client.Agent()
	return ConsulAgent{agent: agent}
}

type Member struct {
	Name string
	IP   string
	Port uint16
}

type Members []Member

func buildMember(name string, ip string, port uint16) Member {
	return Member{Name: name, IP: ip, Port: port}
}

func (r *ConsulAgent) members() Members {
	list := Members{}
	use_wan := false
	members, _ := r.agent.Members(use_wan)
	for _, member := range members {
		list = append(list, buildMember(member.Name, member.Addr, member.Port))
	}
	return list
}

func buildService(id string, name string, port int, ip string) consulapi.AgentServiceRegistration {
	return consulapi.AgentServiceRegistration{ID: id, Name: name, Port: port, Address: ip}
}

func (r *ConsulAgent) registerService(id string, name string, port int, ip string) error {
	srv := buildService(id, name, port, ip)
	if err := r.agent.ServiceRegister(&srv); err != nil {
		return err
	}
	return nil
}

func (r *ConsulAgent) deregisterService(id string) error {
	if err := r.agent.ServiceDeregister(id); err != nil {
		return err
	}
	return nil
}

func (r *ConsulAgent) services() (map[string]*consulapi.AgentService, error) {
	if services, err := r.agent.Services(); err != nil {
		return services, err
	} else {
		return services, nil
	}
}

func main() {
	client, _ := NewConsulClient()
	agent := client.NewConsulAgent()

	fmt.Println(agent.members())
	fmt.Println(agent.services())

	agent.registerService("docker_id_here", "srv-search", 1234, "127.0.0.1")
	time.Sleep(20 * time.Second)

	agent.deregisterService("docker_id_here")
}
<|endoftext|>


<commit_before>package goblet

import (
	"errors"
	"fmt"
	"net/http"
)

// CookieIsMissing is returned when a cookie is missing.
var CookieIsMissing error = errors.New("Cookie is missing")

// SignedCookieIsMissing is returned when the signed cookie is missing.
var SignedCookieIsMissing error = errors.New("Signed cookie is missing")

// CookieNotValid is returned when the cookie and its signed counterpart do not match.
//
// I.e. the cookie value has been tampered with.
var CookieNotValid error = errors.New("Cookie and signed cookie do not match")

var (
	// SignedCookieFormat is the format string used to decide the name of the
	// signed cookie.
	SignedCookieFormat string = "%s_signed"
)

// toSignedCookieName gets the signed cookie name from the specified cookie name,
// by running it through the SignedCookieFormat string.
func toSignedCookieName(name string) string {
	return fmt.Sprintf(SignedCookieFormat, name)
}

// AddSignedCookie adds the specified cookie to the response and also adds an
// additional 'signed' cookie that is used to validate the cookies value when
// SignedCookie is called.
func (c *Context) AddSignedCookie(cookie *http.Cookie) (*http.Cookie, error) {

	// make the signed cookie
	signedCookie := new(http.Cookie)

	// copy the cookie settings
	signedCookie.Path = cookie.Path
	signedCookie.Domain = cookie.Domain
	signedCookie.RawExpires = cookie.RawExpires
	signedCookie.Expires = cookie.Expires
	signedCookie.MaxAge = cookie.MaxAge
	signedCookie.Secure = cookie.Secure
	signedCookie.HttpOnly = cookie.HttpOnly
	signedCookie.Raw = cookie.Raw

	// set the signed cookie specifics
	signedCookie.Name = toSignedCookieName(cookie.Name)
	signedCookie.Value = c.Server.Hash(cookie.Value)

	// add the cookies
	http.SetCookie(c.writer, cookie)
	http.SetCookie(c.writer, signedCookie)

	// return the new signed cookie (and no error)
	return signedCookie, nil

}

func (c *Context) AddCookie(cookie *http.Cookie) error {

	// add the cookies
	http.SetCookie(c.writer, cookie)

	// return the new signed cookie (and no error)
	return nil

}

// Gets the cookie specified by name and validates that its value has not been
// tampered with by checking the signed cookie too.  Will return CookieNotValid error
// if it has been tampered with, otherwise, it will return the actual cookie.
func (c *Context) SignedCookie(name string) (*http.Cookie, error) {

	valid, validErr := c.cookieIsValid(name)
	if valid {
		return c.request.Cookie(name)
	} else if validErr != nil {
		return nil, validErr
	}

	return nil, CookieNotValid
}

// cookieIsValid checks to see if the cookie and its signed counterpart
// match.
func (c *Context) cookieIsValid(name string) (bool, error) {

	// get the cookies
	cookie, cookieErr := c.request.Cookie(name)
	signedCookie, signedCookieErr := c.request.Cookie(toSignedCookieName(name))

	// handle errors reading cookies
	if cookieErr == http.ErrNoCookie {
		return false, CookieIsMissing
	}
	if cookieErr != nil {
		return false, cookieErr
	}
	if signedCookieErr == http.ErrNoCookie {
		return false, SignedCookieIsMissing
	}
	if signedCookieErr != nil {
		return false, signedCookieErr
	}

	// check the cookies
	if c.Server.Hash(cookie.Value) != signedCookie.Value {
		return false, nil
	}

	// success - therefore valid
	return true, nil

}
<commit_msg>add GetCookie<commit_after>package goblet

import (
	"errors"
	"fmt"
	"net/http"
)

// CookieIsMissing is returned when a cookie is missing.
var CookieIsMissing error = errors.New("Cookie is missing")

// SignedCookieIsMissing is returned when the signed cookie is missing.
var SignedCookieIsMissing error = errors.New("Signed cookie is missing")

// CookieNotValid is returned when the cookie and its signed counterpart do not match.
//
// I.e. the cookie value has been tampered with.
var CookieNotValid error = errors.New("Cookie and signed cookie do not match")

var (
	// SignedCookieFormat is the format string used to decide the name of the
	// signed cookie.
	SignedCookieFormat string = "%s_signed"
)

// toSignedCookieName gets the signed cookie name from the specified cookie name,
// by running it through the SignedCookieFormat string.
func toSignedCookieName(name string) string {
	return fmt.Sprintf(SignedCookieFormat, name)
}

// AddSignedCookie adds the specified cookie to the response and also adds an
// additional 'signed' cookie that is used to validate the cookies value when
// SignedCookie is called.
func (c *Context) AddSignedCookie(cookie *http.Cookie) (*http.Cookie, error) {

	// make the signed cookie
	signedCookie := new(http.Cookie)

	// copy the cookie settings
	signedCookie.Path = cookie.Path
	signedCookie.Domain = cookie.Domain
	signedCookie.RawExpires = cookie.RawExpires
	signedCookie.Expires = cookie.Expires
	signedCookie.MaxAge = cookie.MaxAge
	signedCookie.Secure = cookie.Secure
	signedCookie.HttpOnly = cookie.HttpOnly
	signedCookie.Raw = cookie.Raw

	// set the signed cookie specifics
	signedCookie.Name = toSignedCookieName(cookie.Name)
	signedCookie.Value = c.Server.Hash(cookie.Value)

	// add the cookies
	http.SetCookie(c.writer, cookie)
	http.SetCookie(c.writer, signedCookie)

	// return the new signed cookie (and no error)
	return signedCookie, nil

}

func (c *Context) AddCookie(cookie *http.Cookie) error {

	// add the cookies
	http.SetCookie(c.writer, cookie)

	// return the new signed cookie (and no error)
	return nil

}

// Gets the cookie specified by name and validates that its value has not been
// tampered with by checking the signed cookie too.  Will return CookieNotValid error
// if it has been tampered with, otherwise, it will return the actual cookie.
func (c *Context) SignedCookie(name string) (*http.Cookie, error) {

	valid, validErr := c.cookieIsValid(name)
	if valid {
		return c.request.Cookie(name)
	} else if validErr != nil {
		return nil, validErr
	}

	return nil, CookieNotValid
}

// cookieIsValid checks to see if the cookie and its signed counterpart
// match.
func (c *Context) cookieIsValid(name string) (bool, error) {

	// get the cookies
	cookie, cookieErr := c.request.Cookie(name)
	signedCookie, signedCookieErr := c.request.Cookie(toSignedCookieName(name))

	// handle errors reading cookies
	if cookieErr == http.ErrNoCookie {
		return false, CookieIsMissing
	}
	if cookieErr != nil {
		return false, cookieErr
	}
	if signedCookieErr == http.ErrNoCookie {
		return false, SignedCookieIsMissing
	}
	if signedCookieErr != nil {
		return false, signedCookieErr
	}

	// check the cookies
	if c.Server.Hash(cookie.Value) != signedCookie.Value {
		return false, nil
	}

	// success - therefore valid
	return true, nil
}

func (c *Context) GetCookie(name string) (string, error) {
	c, err := c.request.Cookie(name)
	return c.Value, err
}
<|endoftext|>


<commit_before>package sshvault

import (
	"io/ioutil"
	"os"
	"os/exec"
)

// Create opens $EDITOR default to vi
func (v *vault) Create() ([]byte, error) {
	tmpfile, err := ioutil.TempFile("", v.Fingerprint)
	if err != nil {
		return nil, err
	}
	defer Shred(tmpfile.Name())
	editor := os.Getenv("EDITOR")
	if editor == "" {
		editor = "vi"
	}
	cmd := exec.Command(editor, tmpfile.Name())
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	err = cmd.Run()
	if err != nil {
		return nil, err
	}
	b, err := ioutil.ReadFile(tmpfile.Name())
	if err != nil {
		return nil, err
	}
	return b, nil
}
<commit_msg>create vault from STDIN<commit_after>package sshvault

import (
	"bufio"
	"io/ioutil"
	"os"
	"os/exec"
)

// Create reads from STDIN or opens $EDITOR default to vi
func (v *vault) Create() ([]byte, error) {
	// check if there is someting to read on STDIN
	stat, _ := os.Stdin.Stat()
	if (stat.Mode() & os.ModeCharDevice) == 0 {
		scanner := bufio.NewScanner(os.Stdin)
		scanner.Split(bufio.ScanBytes)
		var stdin []byte
		for scanner.Scan() {
			stdin = append(stdin, scanner.Bytes()...)
		}
		if err := scanner.Err(); err != nil {
			return nil, err
		}
		return stdin, nil
	}

	// use $EDITOR
	tmpfile, err := ioutil.TempFile("", v.Fingerprint)
	if err != nil {
		return nil, err
	}
	defer Shred(tmpfile.Name())
	editor := os.Getenv("EDITOR")
	if editor == "" {
		editor = "vi"
	}
	cmd := exec.Command(editor, tmpfile.Name())
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	err = cmd.Run()
	if err != nil {
		return nil, err
	}
	b, err := ioutil.ReadFile(tmpfile.Name())
	if err != nil {
		return nil, err
	}
	return b, nil
}
<|endoftext|>


<commit_before>// +build darwin linux
package main

import (
	"fmt"
	"github.com/CyrusBiotechnology/censusd"
	"net"
	"time"
)

func daemon(minUptime time.Duration, maxUptime time.Duration, minPeers int, maxPeers int, keyPollInterval time.Duration) error {
	// Should we process errors here?
	uptime, _ := getUptime()

	done := make(chan struct{})
	listen := net.UDPAddr{
		IP:   net.IPv4(0, 0, 0, 0),
		Port: 19091,
	}
	bcast := net.UDPAddr{
		IP:   net.IPv4(192, 168, 0, 255),
		Port: 19091,
	}

	stats, err := censusd.Serve(done, "udp4", &listen, &bcast)
	if err != nil {
		panic(err)
	}

	if uptime < minUptime {
		wait := (minUptime - uptime)
		Info.Println(fmt.Sprintf("waiting %v for configured minimum uptime", wait))
		time.Sleep(wait)
	}

	keysTicker := time.NewTicker(keyPollInterval)
	for _ = range keysTicker.C {
		uptime, _ := getUptime()
		stats.Mutex.RLock()
		peers := stats.Nodes
		stats.Mutex.RUnlock()
		if maxUptime > time.Duration(0) && uptime > maxUptime {
			Info.Println("this node is too old!", uptime)
			Info.Println("uptime:", uptime, "peers:", peers)
			close(done)
			return nil
		}
		if minUptime > uptime {
			continue
		}
		if peers <= minPeers {
			continue
		}
		Info.Println("conditions satisfied. uptime:", uptime, "peers:", peers, "/", minPeers)
		close(done)
		return nil
	}
	panic("how did we get here?")
}
<commit_msg>daemon mode is feature-complete<commit_after>// +build darwin linux
package main

import (
	"fmt"
	"github.com/CyrusBiotechnology/censusd"
	"net"
	"time"
)

func daemon(minUptime time.Duration, maxUptime time.Duration, minPeers int, maxPeers int, keyPollInterval time.Duration) error {
	// Should we process errors here?
	uptime, _ := getUptime()

	done := make(chan struct{})
	listen := net.UDPAddr{
		IP:   net.IPv4(0, 0, 0, 0),
		Port: 19091,
	}

	stats, err := censusd.Serve(done, "udp4", &listen)
	if err != nil {
		panic(err)
	}

	if uptime < minUptime {
		wait := (minUptime - uptime)
		Info.Println(fmt.Sprintf("waiting %v for configured minimum uptime", wait))
		time.Sleep(wait)
	}

	keysTicker := time.NewTicker(keyPollInterval)
	for _ = range keysTicker.C {
		uptime, _ := getUptime()
		stats.Mutex.RLock()
		peers := stats.Nodes
		stats.Mutex.RUnlock()
		if maxUptime > time.Duration(0) && uptime > maxUptime {
			Info.Println("this node is too old!", uptime)
			Info.Println("uptime:", uptime, "peers:", peers)
			close(done)
			return nil
		}
		if minUptime > uptime {
			continue
		}
		if peers <= minPeers {
			continue
		}
		Info.Println("conditions satisfied. uptime:", uptime, "peers:", peers, "/", minPeers)
		close(done)
		return nil
	}
	panic("how did we get here?")
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"code.google.com/p/go.exp/fsnotify"
	"errors"
	"fmt"
	"gnd.la/log"
	"net"
	"os"
	"os/signal"
	"os/user"
	"path/filepath"
	"sort"
	"strings"
	"sync"
	"text/tabwriter"
)

var services struct {
	sync.Mutex
	list []*Service
}

type servicesByPriority []*Service

func (s servicesByPriority) Len() int           { return len(s) }
func (s servicesByPriority) Less(i, j int) bool { return s[i].Config.Priority < s[j].Config.Priority }
func (s servicesByPriority) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
func (s servicesByPriority) Sort()              { sort.Stable(s) }

type quit struct {
	stop    chan bool
	stopped chan bool
}

func newQuit() *quit {
	return &quit{
		stop:    make(chan bool, 1),
		stopped: make(chan bool, 1),
	}
}

func (q *quit) sendStop() {
	q.stop <- true
}

func (q *quit) sendStopped() {
	q.stopped <- true
}

func ensureUniqueName(cfg *Config) {
	ii := 1
	orig := cfg.ServiceName()
	for {
		name := cfg.ServiceName()
		unique := true
		for _, v := range services.list {
			if name == v.Name() {
				unique = false
				cfg.Name = fmt.Sprintf("%s-%d", orig, ii)
				ii++
				break
			}
		}
		if unique {
			break
		}
	}
}

func serviceByFilename(name string) (int, *Service) {
	for ii, v := range services.list {
		if v.Config.File == name {
			return ii, v
		}
	}
	return -1, nil
}

func startWatching(q *quit) error {
	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		return err
	}
	go func() {
	End:
		for {
			select {
			case ev := <-watcher.Event:
				name := filepath.Base(ev.Name)
				fmt.Println(name, ev)
				if shouldIgnoreFile(name) {
					break
				}
				services.Lock()
				switch {
				case ev.IsCreate():
					cfg := ParseConfig(name)
					// If a file is moved or copied over an already existing
					// service configuration, we only receive a CREATE. Check
					// if we already have a configuration with that name and, in
					// that case, stop it, update its config and restart.
					if _, s := serviceByFilename(name); s != nil {
						s.updateConfig(cfg)
						servicesByPriority(services.list).Sort()
					} else {
						ensureUniqueName(cfg)
						log.Debugf("added service %s", cfg.ServiceName())
						s := newService(cfg)
						services.list = append(services.list, s)
						servicesByPriority(services.list).Sort()
						s.Start()
					}
				case ev.IsDelete() || ev.IsRename():
					if ii, s := serviceByFilename(name); s != nil {
						log.Debugf("removed service %s", s.Name())
						if s.State == StateStarted {
							s.Stop()
						}
						services.list = append(services.list[:ii], services.list[ii+1:]...)
					}
				case ev.IsModify():
					if _, s := serviceByFilename(name); s != nil {
						cfg := ParseConfig(name)
						s.updateConfig(cfg)
						servicesByPriority(services.list).Sort()
					}
				default:
					log.Errorf("unhandled event: %s\n", ev)
				}
				services.Unlock()
			case err := <-watcher.Error:
				log.Errorf("error watching: %s", err)
			case <-q.stop:
				watcher.Close()
				q.sendStopped()
				break End
			}
		}
	}()
	if err := watcher.Watch(servicesDir()); err != nil {
		return err
	}
	return nil
}

func startService(conn net.Conn, s *Service) error {
	name := s.Name()
	encodeResponse(conn, respOk, fmt.Sprintf("starting %s\n", name))
	if serr := s.Start(); serr != nil {
		return encodeResponse(conn, respErr, fmt.Sprintf("error starting %s: %s\n", name, serr))
	}
	return encodeResponse(conn, respOk, fmt.Sprintf("started %s\n", name))
}

func stopService(conn net.Conn, s *Service) (bool, error) {
	name := s.Name()
	encodeResponse(conn, respOk, fmt.Sprintf("stopping %s\n", name))
	if serr := s.Stop(); serr != nil {
		return false, encodeResponse(conn, respErr, fmt.Sprintf("error stopping %s: %s\n", name, serr))
	}
	return true, encodeResponse(conn, respOk, fmt.Sprintf("stopped %s\n", name))
}

func serveConn(conn net.Conn) error {
	defer conn.Close()
	args, err := decodeArgs(conn)
	if err != nil {
		return fmt.Errorf("error decoding arguments: %s", err)
	}
	if len(args) > 0 {
		var err error
		var st *Service
		var name string
		cmd := strings.ToLower(args[0])
		if cmd == "start" || cmd == "stop" || cmd == "restart" || cmd == "log" {
			if len(args) != 2 {
				err = encodeResponse(conn, respErr, fmt.Sprintf("command %s requires exactly one argument\n", cmd))
				cmd = ""
			}
			if cmd != "" {
				services.Lock()
				for _, v := range services.list {
					if sn := v.Name(); sn == args[1] {
						st = v
						name = sn
						break
					}
				}
				services.Unlock()
				if st == nil {
					err = encodeResponse(conn, respErr, fmt.Sprintf("no service named %s\n", args[1]))
					cmd = ""
				}
			}
		}
		switch cmd {
		case "":
			// cmd already handled
		case "start":
			if st.State == StateStarted {
				err = encodeResponse(conn, respOk, fmt.Sprintf("%s is already running\n", name))
			} else {
				err = startService(conn, st)
			}
		case "stop":
			if st.State != StateStarted {
				err = encodeResponse(conn, respOk, fmt.Sprintf("%s is not running\n", name))
			} else {
				_, err = stopService(conn, st)
			}
		case "restart":
			var stopped bool
			if st.State == StateStarted {
				stopped, err = stopService(conn, st)
			}
			if stopped {
				err = startService(conn, st)
			}
		case "list":
			var buf bytes.Buffer
			w := tabwriter.NewWriter(&buf, 4, 4, 4, ' ', 0)
			fmt.Fprint(w, "SERVICE\tSTATUS\t\n")
			services.Lock()
			for _, v := range services.list {
				fmt.Fprintf(w, "%s\t", v.Name())
				switch v.State {
				case StateStopped:
					fmt.Fprint(w, "STOPPED")
				case StateStopping:
					fmt.Fprint(w, "STOPPING")
				case StateStarting:
					fmt.Fprint(w, "STARTING")
				case StateStarted:
					if v.Restarts > 0 {
						fmt.Fprintf(w, "RUNNING since %s - %d restarts", formatTime(v.Started), v.Restarts)
					} else {
						fmt.Fprintf(w, "RUNNING since %s", formatTime(v.Started))
					}
				case StateFailed:
					fmt.Fprintf(w, "FAILED - %s", v.Err)
				default:
					panic("invalid state")
				}
				fmt.Fprint(w, "\t\n")
			}
			services.Unlock()
			w.Flush()
			buf.WriteString("\n")
			err = encodeResponse(conn, respOk, buf.String())
		case "log":
			if st.State != StateStarted {
				err = encodeResponse(conn, respErr, fmt.Sprintf("%s is not running\n", name))
				break
			}
			if st.logger.monitor != nil {
				err = encodeResponse(conn, respErr, fmt.Sprintf("%s is already being monitored\n", name))
				break
			}
			ch := make(chan bool, 1)
			st.logger.monitor = func(prefix string, b []byte) {
				var buf bytes.Buffer
				buf.WriteByte('[')
				buf.WriteString(prefix)
				buf.WriteString("] ")
				buf.Write(b)
				if b[len(b)-1] != '\n' {
					buf.Write(newLine)
				}
				encodeResponse(conn, respOk, buf.String())
			}
			go func() {
				// log stops when the client sends something over the connection
				// or the connection is closed
				b := make([]byte, 1)
				conn.Read(b)
				conn.Close()
				ch <- true
			}()
			<-ch
			st.logger.monitor = nil
			return nil
		default:
			err = encodeResponse(conn, respErr, fmt.Sprintf("unknown command %s - %s\n", cmd, help))
			if err != nil {
				return err
			}
		}
	}
	return encodeResponse(conn, respEnd, "")
}

func startServer(q *quit) error {
	os.Remove(SocketPath)
	server, err := net.Listen("unix", SocketPath)
	if err != nil {
		return err
	}
	if gid := getGroupId(AppName); gid >= 0 {
		os.Chown(SocketPath, 0, gid)
		os.Chmod(SocketPath, 0775)
	}
	conns := make(chan net.Conn, 10)
	go func() {
		for {
			conn, err := server.Accept()
			if err != nil {
				log.Errorf("error accepting connection: %s", err)
			}
			conns <- conn
		}
	}()
	go func() {
		for {
			select {
			case <-q.stop:
				os.Remove(SocketPath)
				q.sendStopped()
				return
			case conn := <-conns:
				go func() {
					if err := serveConn(conn); err != nil {
						log.Errorf("error serving connection: %s", err)
					}
				}()
			}
		}
	}()
	return nil
}

func daemonMain() error {
	u, err := user.Current()
	if err != nil {
		return err
	}
	if u.Uid != "0" {
		return errors.New("govenator daemon must be run as root")
	}
	// Make logs directory
	os.Mkdir(LogDir, 0755)
	configs, err := ParseConfigs()
	if err != nil {
		return err
	}
	services.Lock()
	services.list = make([]*Service, 0, len(configs))
	for _, v := range configs {
		ensureUniqueName(v)
		s := newService(v)
		services.list = append(services.list, s)
		s.Start()
	}
	servicesByPriority(services.list).Sort()
	services.Unlock()
	quitWatcher := newQuit()
	if err := startWatching(quitWatcher); err != nil {
		log.Errorf("error watching %s, configuration won't be automatically updated: %s", servicesDir(), err)
	}
	quitServer := newQuit()
	if err := startServer(quitServer); err != nil {
		log.Errorf("error starting server, can't receive remote commands: %s", err)
	}
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, os.Kill)
	// Wait for signal
	<-c
	quitWatcher.sendStop()
	quitServer.sendStop()
	// Wait for goroutines to exit cleanly
	<-quitWatcher.stopped
	<-quitServer.stopped
	services.Lock()
	var wg sync.WaitGroup
	wg.Add(len(services.list))
	// Stop in reverse order, to respect priorities
	for ii := len(services.list) - 1; ii >= 0; ii-- {
		v := services.list[ii]
		go func(s *Service) {
			s.Stop()
			wg.Done()
		}(v)
	}
	wg.Wait()
	services.Unlock()
	log.Debugf("daemon exiting")
	return nil
}
<commit_msg>Add undocumented command for obtaining configuration parameters<commit_after>package main

import (
	"bytes"
	"code.google.com/p/go.exp/fsnotify"
	"errors"
	"fmt"
	"gnd.la/log"
	"net"
	"os"
	"os/signal"
	"os/user"
	"path/filepath"
	"sort"
	"strings"
	"sync"
	"text/tabwriter"
)

var services struct {
	sync.Mutex
	list []*Service
}

type servicesByPriority []*Service

func (s servicesByPriority) Len() int           { return len(s) }
func (s servicesByPriority) Less(i, j int) bool { return s[i].Config.Priority < s[j].Config.Priority }
func (s servicesByPriority) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
func (s servicesByPriority) Sort()              { sort.Stable(s) }

type quit struct {
	stop    chan bool
	stopped chan bool
}

func newQuit() *quit {
	return &quit{
		stop:    make(chan bool, 1),
		stopped: make(chan bool, 1),
	}
}

func (q *quit) sendStop() {
	q.stop <- true
}

func (q *quit) sendStopped() {
	q.stopped <- true
}

func ensureUniqueName(cfg *Config) {
	ii := 1
	orig := cfg.ServiceName()
	for {
		name := cfg.ServiceName()
		unique := true
		for _, v := range services.list {
			if name == v.Name() {
				unique = false
				cfg.Name = fmt.Sprintf("%s-%d", orig, ii)
				ii++
				break
			}
		}
		if unique {
			break
		}
	}
}

func serviceByFilename(name string) (int, *Service) {
	for ii, v := range services.list {
		if v.Config.File == name {
			return ii, v
		}
	}
	return -1, nil
}

func startWatching(q *quit) error {
	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		return err
	}
	go func() {
	End:
		for {
			select {
			case ev := <-watcher.Event:
				name := filepath.Base(ev.Name)
				fmt.Println(name, ev)
				if shouldIgnoreFile(name) {
					break
				}
				services.Lock()
				switch {
				case ev.IsCreate():
					cfg := ParseConfig(name)
					// If a file is moved or copied over an already existing
					// service configuration, we only receive a CREATE. Check
					// if we already have a configuration with that name and, in
					// that case, stop it, update its config and restart.
					if _, s := serviceByFilename(name); s != nil {
						s.updateConfig(cfg)
						servicesByPriority(services.list).Sort()
					} else {
						ensureUniqueName(cfg)
						log.Debugf("added service %s", cfg.ServiceName())
						s := newService(cfg)
						services.list = append(services.list, s)
						servicesByPriority(services.list).Sort()
						s.Start()
					}
				case ev.IsDelete() || ev.IsRename():
					if ii, s := serviceByFilename(name); s != nil {
						log.Debugf("removed service %s", s.Name())
						if s.State == StateStarted {
							s.Stop()
						}
						services.list = append(services.list[:ii], services.list[ii+1:]...)
					}
				case ev.IsModify():
					if _, s := serviceByFilename(name); s != nil {
						cfg := ParseConfig(name)
						s.updateConfig(cfg)
						servicesByPriority(services.list).Sort()
					}
				default:
					log.Errorf("unhandled event: %s\n", ev)
				}
				services.Unlock()
			case err := <-watcher.Error:
				log.Errorf("error watching: %s", err)
			case <-q.stop:
				watcher.Close()
				q.sendStopped()
				break End
			}
		}
	}()
	if err := watcher.Watch(servicesDir()); err != nil {
		return err
	}
	return nil
}

func startService(conn net.Conn, s *Service) error {
	name := s.Name()
	encodeResponse(conn, respOk, fmt.Sprintf("starting %s\n", name))
	if serr := s.Start(); serr != nil {
		return encodeResponse(conn, respErr, fmt.Sprintf("error starting %s: %s\n", name, serr))
	}
	return encodeResponse(conn, respOk, fmt.Sprintf("started %s\n", name))
}

func stopService(conn net.Conn, s *Service) (bool, error) {
	name := s.Name()
	encodeResponse(conn, respOk, fmt.Sprintf("stopping %s\n", name))
	if serr := s.Stop(); serr != nil {
		return false, encodeResponse(conn, respErr, fmt.Sprintf("error stopping %s: %s\n", name, serr))
	}
	return true, encodeResponse(conn, respOk, fmt.Sprintf("stopped %s\n", name))
}

func serveConn(conn net.Conn) error {
	defer conn.Close()
	args, err := decodeArgs(conn)
	if err != nil {
		return fmt.Errorf("error decoding arguments: %s", err)
	}
	if len(args) > 0 {
		var err error
		var st *Service
		var name string
		cmd := strings.ToLower(args[0])
		if cmd == "start" || cmd == "stop" || cmd == "restart" || cmd == "log" {
			if len(args) != 2 {
				err = encodeResponse(conn, respErr, fmt.Sprintf("command %s requires exactly one argument\n", cmd))
				cmd = ""
			}
			if cmd != "" {
				services.Lock()
				for _, v := range services.list {
					if sn := v.Name(); sn == args[1] {
						st = v
						name = sn
						break
					}
				}
				services.Unlock()
				if st == nil {
					err = encodeResponse(conn, respErr, fmt.Sprintf("no service named %s\n", args[1]))
					cmd = ""
				}
			}
		}
		switch cmd {
		case "":
			// cmd already handled
		case "start":
			if st.State == StateStarted {
				err = encodeResponse(conn, respOk, fmt.Sprintf("%s is already running\n", name))
			} else {
				err = startService(conn, st)
			}
		case "stop":
			if st.State != StateStarted {
				err = encodeResponse(conn, respOk, fmt.Sprintf("%s is not running\n", name))
			} else {
				_, err = stopService(conn, st)
			}
		case "restart":
			var stopped bool
			if st.State == StateStarted {
				stopped, err = stopService(conn, st)
			}
			if stopped {
				err = startService(conn, st)
			}
		case "list":
			var buf bytes.Buffer
			w := tabwriter.NewWriter(&buf, 4, 4, 4, ' ', 0)
			fmt.Fprint(w, "SERVICE\tSTATUS\t\n")
			services.Lock()
			for _, v := range services.list {
				fmt.Fprintf(w, "%s\t", v.Name())
				switch v.State {
				case StateStopped:
					fmt.Fprint(w, "STOPPED")
				case StateStopping:
					fmt.Fprint(w, "STOPPING")
				case StateStarting:
					fmt.Fprint(w, "STARTING")
				case StateStarted:
					if v.Restarts > 0 {
						fmt.Fprintf(w, "RUNNING since %s - %d restarts", formatTime(v.Started), v.Restarts)
					} else {
						fmt.Fprintf(w, "RUNNING since %s", formatTime(v.Started))
					}
				case StateFailed:
					fmt.Fprintf(w, "FAILED - %s", v.Err)
				default:
					panic("invalid state")
				}
				fmt.Fprint(w, "\t\n")
			}
			services.Unlock()
			w.Flush()
			buf.WriteString("\n")
			err = encodeResponse(conn, respOk, buf.String())
		case "log":
			if st.State != StateStarted {
				err = encodeResponse(conn, respErr, fmt.Sprintf("%s is not running\n", name))
				break
			}
			if st.logger.monitor != nil {
				err = encodeResponse(conn, respErr, fmt.Sprintf("%s is already being monitored\n", name))
				break
			}
			ch := make(chan bool, 1)
			st.logger.monitor = func(prefix string, b []byte) {
				var buf bytes.Buffer
				buf.WriteByte('[')
				buf.WriteString(prefix)
				buf.WriteString("] ")
				buf.Write(b)
				if b[len(b)-1] != '\n' {
					buf.Write(newLine)
				}
				encodeResponse(conn, respOk, buf.String())
			}
			go func() {
				// log stops when the client sends something over the connection
				// or the connection is closed
				b := make([]byte, 1)
				conn.Read(b)
				conn.Close()
				ch <- true
			}()
			<-ch
			st.logger.monitor = nil
			return nil
		case "conf":
			if len(args) != 2 {
				err = encodeResponse(conn, respErr, fmt.Sprintf("conf requires one argument, %d given", len(args)-1))
				break
			}
			var value string
			switch strings.ToLower(args[1]) {
			case "config-dir":
				value = *configDir
			case "services-dir":
				value = servicesDir()
			}
			if !filepath.IsAbs(value) {
				p, err := filepath.Abs(value)
				if err != nil {
					return err
				}
				value = p
			}
			r := respOk
			if value == "" {
				r = respErr
				value = fmt.Sprintf("unknown configuration parameter %q", args[1])
			} else {
				value += "\n"
			}
			err = encodeResponse(conn, r, value)
		default:
			err = encodeResponse(conn, respErr, fmt.Sprintf("unknown command %s - %s\n", cmd, help))
			if err != nil {
				return err
			}
		}
	}
	return encodeResponse(conn, respEnd, "")
}

func startServer(q *quit) error {
	os.Remove(SocketPath)
	server, err := net.Listen("unix", SocketPath)
	if err != nil {
		return err
	}
	if gid := getGroupId(AppName); gid >= 0 {
		os.Chown(SocketPath, 0, gid)
		os.Chmod(SocketPath, 0775)
	}
	conns := make(chan net.Conn, 10)
	go func() {
		for {
			conn, err := server.Accept()
			if err != nil {
				log.Errorf("error accepting connection: %s", err)
			}
			conns <- conn
		}
	}()
	go func() {
		for {
			select {
			case <-q.stop:
				os.Remove(SocketPath)
				q.sendStopped()
				return
			case conn := <-conns:
				go func() {
					if err := serveConn(conn); err != nil {
						log.Errorf("error serving connection: %s", err)
					}
				}()
			}
		}
	}()
	return nil
}

func daemonMain() error {
	u, err := user.Current()
	if err != nil {
		return err
	}
	if u.Uid != "0" {
		return errors.New("govenator daemon must be run as root")
	}
	// Make logs directory
	os.Mkdir(LogDir, 0755)
	configs, err := ParseConfigs()
	if err != nil {
		return err
	}
	services.Lock()
	services.list = make([]*Service, 0, len(configs))
	for _, v := range configs {
		ensureUniqueName(v)
		s := newService(v)
		services.list = append(services.list, s)
		s.Start()
	}
	servicesByPriority(services.list).Sort()
	services.Unlock()
	quitWatcher := newQuit()
	if err := startWatching(quitWatcher); err != nil {
		log.Errorf("error watching %s, configuration won't be automatically updated: %s", servicesDir(), err)
	}
	quitServer := newQuit()
	if err := startServer(quitServer); err != nil {
		log.Errorf("error starting server, can't receive remote commands: %s", err)
	}
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, os.Kill)
	// Wait for signal
	<-c
	quitWatcher.sendStop()
	quitServer.sendStop()
	// Wait for goroutines to exit cleanly
	<-quitWatcher.stopped
	<-quitServer.stopped
	services.Lock()
	var wg sync.WaitGroup
	wg.Add(len(services.list))
	// Stop in reverse order, to respect priorities
	for ii := len(services.list) - 1; ii >= 0; ii-- {
		v := services.list[ii]
		go func(s *Service) {
			s.Stop()
			wg.Done()
		}(v)
	}
	wg.Wait()
	services.Unlock()
	log.Debugf("daemon exiting")
	return nil
}
<|endoftext|>


<commit_before>package dotweb

// Global define
const (
	// Version current version
	Version = "1.7.12"
)

// Log define
const (
	LogTarget_Default        = "dotweb_default"
	LogTarget_HttpRequest    = "dotweb_request"
	LogTarget_HttpServer     = "dotweb_server"
	LogTarget_RequestTimeout = "dotweb_req_timeout"

	LogLevel_Debug = "debug"
	LogLevel_Info  = "info"
	LogLevel_Warn  = "warn"
	LogLevel_Error = "error"
)

// Http define
const (
	CharsetUTF8       = "charset=utf-8"
	DefaultServerName = "dotweb"
)

const (
	Windows = "windows"
	Linux   = "linux"
)

// MIME types
const (
	MIMEApplicationJSON                  = "application/json"
	MIMEApplicationJSONCharsetUTF8       = MIMEApplicationJSON + "; " + CharsetUTF8
	MIMEApplicationJavaScript            = "application/javascript"
	MIMEApplicationJavaScriptCharsetUTF8 = MIMEApplicationJavaScript + "; " + CharsetUTF8
	MIMEApplicationXML                   = "application/xml"
	MIMEApplicationXMLCharsetUTF8        = MIMEApplicationXML + "; " + CharsetUTF8
	MIMEApplicationForm                  = "application/x-www-form-urlencoded"
	MIMEApplicationProtobuf              = "application/protobuf"
	MIMEApplicationMsgpack               = "application/msgpack"
	MIMETextHTML                         = "text/html"
	MIMETextHTMLCharsetUTF8              = MIMETextHTML + "; " + CharsetUTF8
	MIMETextPlain                        = "text/plain"
	MIMETextPlainCharsetUTF8             = MIMETextPlain + "; " + CharsetUTF8
	MIMEMultipartForm                    = "multipart/form-data"
	MIMEOctetStream                      = "application/octet-stream"
)

// Headers
const (
	HeaderAcceptEncoding                = "Accept-Encoding"
	HeaderAllow                         = "Allow"
	HeaderAuthorization                 = "Authorization"
	HeaderContentDisposition            = "Content-Disposition"
	HeaderContentEncoding               = "Content-Encoding"
	HeaderContentLength                 = "Content-Length"
	HeaderContentType                   = "Content-Type"
	HeaderCookie                        = "Cookie"
	HeaderSetCookie                     = "Set-Cookie"
	HeaderIfModifiedSince               = "If-Modified-Since"
	HeaderLastModified                  = "Last-Modified"
	HeaderLocation                      = "Location"
	HeaderUpgrade                       = "Upgrade"
	HeaderVary                          = "Vary"
	HeaderWWWAuthenticate               = "WWW-Authenticate"
	HeaderXRequestedWith                = "X-Requested-With"
	HeaderXForwardedProto               = "X-Forwarded-Proto"
	HeaderXHTTPMethodOverride           = "X-HTTP-Method-Override"
	HeaderXForwardedFor                 = "X-Forwarded-For"
	HeaderXRealIP                       = "X-Real-IP"
	HeaderServer                        = "Server"
	HeaderOrigin                        = "Origin"
	HeaderAccessControlRequestMethod    = "Access-Control-Request-Method"
	HeaderAccessControlRequestHeaders   = "Access-Control-Request-Headers"
	HeaderAccessControlAllowOrigin      = "Access-Control-Allow-Origin"
	HeaderAccessControlAllowMethods     = "Access-Control-Allow-Methods"
	HeaderAccessControlAllowHeaders     = "Access-Control-Allow-Headers"
	HeaderAccessControlAllowCredentials = "Access-Control-Allow-Credentials"
	HeaderAccessControlExposeHeaders    = "Access-Control-Expose-Headers"
	HeaderAccessControlMaxAge           = "Access-Control-Max-Age"
	HeaderP3P                           = "P3P"
	HeaderCacheControl                  = "Cache-control"

	// Security
	HeaderStrictTransportSecurity = "Strict-Transport-Security"
	HeaderXContentTypeOptions     = "X-Content-Type-Options"
	HeaderXXSSProtection          = "X-XSS-Protection"
	HeaderXFrameOptions           = "X-Frame-Options"
	HeaderContentSecurityPolicy   = "Content-Security-Policy"
	HeaderXCSRFToken              = "X-CSRF-Token"
)

const (
	HeaderRequestID    = "d_request_id"
	HeaderResponseTime = "d_response_time"
)
<commit_msg>update version info<commit_after>package dotweb

// Global define
const (
	// Version current version
	Version = "1.7.16"
)

// Log define
const (
	LogTarget_Default        = "dotweb_default"
	LogTarget_HttpRequest    = "dotweb_request"
	LogTarget_HttpServer     = "dotweb_server"
	LogTarget_RequestTimeout = "dotweb_req_timeout"

	LogLevel_Debug = "debug"
	LogLevel_Info  = "info"
	LogLevel_Warn  = "warn"
	LogLevel_Error = "error"
)

// Http define
const (
	CharsetUTF8       = "charset=utf-8"
	DefaultServerName = "dotweb"
)

const (
	Windows = "windows"
	Linux   = "linux"
)

// MIME types
const (
	MIMEApplicationJSON                  = "application/json"
	MIMEApplicationJSONCharsetUTF8       = MIMEApplicationJSON + "; " + CharsetUTF8
	MIMEApplicationJavaScript            = "application/javascript"
	MIMEApplicationJavaScriptCharsetUTF8 = MIMEApplicationJavaScript + "; " + CharsetUTF8
	MIMEApplicationXML                   = "application/xml"
	MIMEApplicationXMLCharsetUTF8        = MIMEApplicationXML + "; " + CharsetUTF8
	MIMEApplicationForm                  = "application/x-www-form-urlencoded"
	MIMEApplicationProtobuf              = "application/protobuf"
	MIMEApplicationMsgpack               = "application/msgpack"
	MIMETextHTML                         = "text/html"
	MIMETextHTMLCharsetUTF8              = MIMETextHTML + "; " + CharsetUTF8
	MIMETextPlain                        = "text/plain"
	MIMETextPlainCharsetUTF8             = MIMETextPlain + "; " + CharsetUTF8
	MIMEMultipartForm                    = "multipart/form-data"
	MIMEOctetStream                      = "application/octet-stream"
)

// Headers
const (
	HeaderAcceptEncoding                = "Accept-Encoding"
	HeaderAllow                         = "Allow"
	HeaderAuthorization                 = "Authorization"
	HeaderContentDisposition            = "Content-Disposition"
	HeaderContentEncoding               = "Content-Encoding"
	HeaderContentLength                 = "Content-Length"
	HeaderContentType                   = "Content-Type"
	HeaderCookie                        = "Cookie"
	HeaderSetCookie                     = "Set-Cookie"
	HeaderIfModifiedSince               = "If-Modified-Since"
	HeaderLastModified                  = "Last-Modified"
	HeaderLocation                      = "Location"
	HeaderUpgrade                       = "Upgrade"
	HeaderVary                          = "Vary"
	HeaderWWWAuthenticate               = "WWW-Authenticate"
	HeaderXRequestedWith                = "X-Requested-With"
	HeaderXForwardedProto               = "X-Forwarded-Proto"
	HeaderXHTTPMethodOverride           = "X-HTTP-Method-Override"
	HeaderXForwardedFor                 = "X-Forwarded-For"
	HeaderXRealIP                       = "X-Real-IP"
	HeaderServer                        = "Server"
	HeaderOrigin                        = "Origin"
	HeaderAccessControlRequestMethod    = "Access-Control-Request-Method"
	HeaderAccessControlRequestHeaders   = "Access-Control-Request-Headers"
	HeaderAccessControlAllowOrigin      = "Access-Control-Allow-Origin"
	HeaderAccessControlAllowMethods     = "Access-Control-Allow-Methods"
	HeaderAccessControlAllowHeaders     = "Access-Control-Allow-Headers"
	HeaderAccessControlAllowCredentials = "Access-Control-Allow-Credentials"
	HeaderAccessControlExposeHeaders    = "Access-Control-Expose-Headers"
	HeaderAccessControlMaxAge           = "Access-Control-Max-Age"
	HeaderP3P                           = "P3P"
	HeaderCacheControl                  = "Cache-control"

	// Security
	HeaderStrictTransportSecurity = "Strict-Transport-Security"
	HeaderXContentTypeOptions     = "X-Content-Type-Options"
	HeaderXXSSProtection          = "X-XSS-Protection"
	HeaderXFrameOptions           = "X-Frame-Options"
	HeaderContentSecurityPolicy   = "Content-Security-Policy"
	HeaderXCSRFToken              = "X-CSRF-Token"
)

const (
	HeaderRequestID    = "d_request_id"
	HeaderResponseTime = "d_response_time"
)
<|endoftext|>


<commit_before>package cruncy

// VERSION of the application
const VERSION = "0.4.3"
<commit_msg>0.4.4<commit_after>package cruncy

// VERSION of the application
const VERSION = "0.4.4"
<|endoftext|>


<commit_before>package bolt

import (
	"bytes"
	"sort"
)

// Cursor represents an iterator that can traverse over all key/value pairs in a bucket in sorted order.
// Cursors can be obtained from a transaction and are valid as long as the transaction is open.
type Cursor struct {
	bucket *Bucket
	stack  []elemRef
}

// Bucket returns the bucket that this cursor was created from.
func (c *Cursor) Bucket() *Bucket {
	return c.bucket
}

// First moves the cursor to the first item in the bucket and returns its key and value.
// If the bucket is empty then a nil key and value are returned.
func (c *Cursor) First() (key []byte, value []byte) {
	_assert(c.bucket.tx.db != nil, "tx closed")
	c.stack = c.stack[:0]
	p, n := c.bucket.pageNode(c.bucket.root)
	c.stack = append(c.stack, elemRef{page: p, node: n, index: 0})
	c.first()
	k, v, flags := c.keyValue()
	if (flags & uint32(bucketLeafFlag)) != 0 {
		return k, nil
	}
	return k, v

}

// Last moves the cursor to the last item in the bucket and returns its key and value.
// If the bucket is empty then a nil key and value are returned.
func (c *Cursor) Last() (key []byte, value []byte) {
	_assert(c.bucket.tx.db != nil, "tx closed")
	c.stack = c.stack[:0]
	p, n := c.bucket.pageNode(c.bucket.root)
	ref := elemRef{page: p, node: n}
	ref.index = ref.count() - 1
	c.stack = append(c.stack, ref)
	c.last()
	k, v, flags := c.keyValue()
	if (flags & uint32(bucketLeafFlag)) != 0 {
		return k, nil
	}
	return k, v
}

// Next moves the cursor to the next item in the bucket and returns its key and value.
// If the cursor is at the end of the bucket then a nil key and value are returned.
func (c *Cursor) Next() (key []byte, value []byte) {
	_assert(c.bucket.tx.db != nil, "tx closed")

	// Attempt to move over one element until we're successful.
	// Move up the stack as we hit the end of each page in our stack.
	for i := len(c.stack) - 1; i >= 0; i-- {
		elem := &c.stack[i]
		if elem.index < elem.count()-1 {
			elem.index++
			break
		}
		c.stack = c.stack[:i]
	}

	// If we've hit the end then return nil.
	if len(c.stack) == 0 {
		return nil, nil
	}

	// Move down the stack to find the first element of the first leaf under this branch.
	c.first()
	k, v, flags := c.keyValue()
	if (flags & uint32(bucketLeafFlag)) != 0 {
		return k, nil
	}
	return k, v
}

// Prev moves the cursor to the previous item in the bucket and returns its key and value.
// If the cursor is at the beginning of the bucket then a nil key and value are returned.
func (c *Cursor) Prev() (key []byte, value []byte) {
	_assert(c.bucket.tx.db != nil, "tx closed")

	// Attempt to move back one element until we're successful.
	// Move up the stack as we hit the beginning of each page in our stack.
	for i := len(c.stack) - 1; i >= 0; i-- {
		elem := &c.stack[i]
		if elem.index > 0 {
			elem.index--
			break
		}
		c.stack = c.stack[:i]
	}

	// If we've hit the end then return nil.
	if len(c.stack) == 0 {
		return nil, nil
	}

	// Move down the stack to find the last element of the last leaf under this branch.
	c.last()
	k, v, flags := c.keyValue()
	if (flags & uint32(bucketLeafFlag)) != 0 {
		return k, nil
	}
	return k, v
}

// Seek moves the cursor to a given key and returns it.
// If the key does not exist then the next key is used. If no keys
// follow, a nil value is returned.
func (c *Cursor) Seek(seek []byte) (key []byte, value []byte) {
	k, v, flags := c.seek(seek)
	if k == nil {
		return nil, nil
	} else if (flags & uint32(bucketLeafFlag)) != 0 {
		return k, nil
	}
	return k, v
}

// seek moves the cursor to a given key and returns it.
// If the key does not exist then the next key is used. If no keys
// follow, a nil value is returned.
func (c *Cursor) seek(seek []byte) (key []byte, value []byte, flags uint32) {
	_assert(c.bucket.tx.db != nil, "tx closed")

	// Start from root page/node and traverse to correct page.
	c.stack = c.stack[:0]
	c.search(seek, c.bucket.root)
	ref := &c.stack[len(c.stack)-1]

	// If the cursor is pointing to the end of page/node then return nil.
	if ref.index >= ref.count() {
		return nil, nil, 0
	}

	// If this is a bucket then return a nil value.
	return c.keyValue()
}

// first moves the cursor to the first leaf element under the last page in the stack.
func (c *Cursor) first() {
	for {
		// Exit when we hit a leaf page.
		ref := &c.stack[len(c.stack)-1]
		if ref.isLeaf() {
			break
		}

		// Keep adding pages pointing to the first element to the stack.
		var pgid pgid
		if ref.node != nil {
			pgid = ref.node.inodes[ref.index].pgid
		} else {
			pgid = ref.page.branchPageElement(uint16(ref.index)).pgid
		}
		p, n := c.bucket.pageNode(pgid)
		c.stack = append(c.stack, elemRef{page: p, node: n, index: 0})
	}
}

// last moves the cursor to the last leaf element under the last page in the stack.
func (c *Cursor) last() {
	for {
		// Exit when we hit a leaf page.
		ref := &c.stack[len(c.stack)-1]
		if ref.isLeaf() {
			break
		}

		// Keep adding pages pointing to the last element in the stack.
		var pgid pgid
		if ref.node != nil {
			pgid = ref.node.inodes[ref.index].pgid
		} else {
			pgid = ref.page.branchPageElement(uint16(ref.index)).pgid
		}
		p, n := c.bucket.pageNode(pgid)

		var nextRef = elemRef{page: p, node: n}
		nextRef.index = nextRef.count() - 1
		c.stack = append(c.stack, nextRef)
	}
}

// search recursively performs a binary search against a given page/node until it finds a given key.
func (c *Cursor) search(key []byte, pgid pgid) {
	p, n := c.bucket.pageNode(pgid)
	if p != nil {
		_assert((p.flags&(branchPageFlag|leafPageFlag)) != 0, "invalid page type: %d: %s", p.id, p.typ())
	}
	e := elemRef{page: p, node: n}
	c.stack = append(c.stack, e)

	// If we're on a leaf page/node then find the specific node.
	if e.isLeaf() {
		c.nsearch(key)
		return
	}

	if n != nil {
		c.searchNode(key, n)
		return
	}
	c.searchPage(key, p)
}

func (c *Cursor) searchNode(key []byte, n *node) {
	var exact bool
	index := sort.Search(len(n.inodes), func(i int) bool {
		// TODO(benbjohnson): Optimize this range search. It's a bit hacky right now.
		// sort.Search() finds the lowest index where f() != -1 but we need the highest index.
		ret := bytes.Compare(n.inodes[i].key, key)
		if ret == 0 {
			exact = true
		}
		return ret != -1
	})
	if !exact && index > 0 {
		index--
	}
	c.stack[len(c.stack)-1].index = index

	// Recursively search to the next page.
	c.search(key, n.inodes[index].pgid)
}

func (c *Cursor) searchPage(key []byte, p *page) {
	// Binary search for the correct range.
	inodes := p.branchPageElements()

	var exact bool
	index := sort.Search(int(p.count), func(i int) bool {
		// TODO(benbjohnson): Optimize this range search. It's a bit hacky right now.
		// sort.Search() finds the lowest index where f() != -1 but we need the highest index.
		ret := bytes.Compare(inodes[i].key(), key)
		if ret == 0 {
			exact = true
		}
		return ret != -1
	})
	if !exact && index > 0 {
		index--
	}
	c.stack[len(c.stack)-1].index = index

	// Recursively search to the next page.
	c.search(key, inodes[index].pgid)
}

// nsearch searches the leaf node on the top of the stack for a key.
func (c *Cursor) nsearch(key []byte) {
	e := &c.stack[len(c.stack)-1]
	p, n := e.page, e.node

	// If we have a node then search its inodes.
	if n != nil {
		index := sort.Search(len(n.inodes), func(i int) bool {
			return bytes.Compare(n.inodes[i].key, key) != -1
		})
		e.index = index
		return
	}

	// If we have a page then search its leaf elements.
	inodes := p.leafPageElements()
	index := sort.Search(int(p.count), func(i int) bool {
		return bytes.Compare(inodes[i].key(), key) != -1
	})
	e.index = index
}

// keyValue returns the key and value of the current leaf element.
func (c *Cursor) keyValue() ([]byte, []byte, uint32) {
	ref := &c.stack[len(c.stack)-1]
	if ref.count() == 0 || ref.index >= ref.count() {
		return nil, nil, 0
	}

	// Retrieve value from node.
	if ref.node != nil {
		inode := &ref.node.inodes[ref.index]
		return inode.key, inode.value, inode.flags
	}

	// Or retrieve value from page.
	elem := ref.page.leafPageElement(uint16(ref.index))
	return elem.key(), elem.value(), elem.flags
}

// node returns the node that the cursor is currently positioned on.
func (c *Cursor) node() *node {
	_assert(len(c.stack) > 0, "accessing a node with a zero-length cursor stack")

	// If the top of the stack is a leaf node then just return it.
	if ref := &c.stack[len(c.stack)-1]; ref.node != nil && ref.isLeaf() {
		return ref.node
	}

	// Start from root and traverse down the hierarchy.
	var n = c.stack[0].node
	if n == nil {
		n = c.bucket.node(c.stack[0].page.id, nil)
	}
	for _, ref := range c.stack[:len(c.stack)-1] {
		_assert(!n.isLeaf, "expected branch node")
		n = n.childAt(int(ref.index))
	}
	_assert(n.isLeaf, "expected leaf node")
	return n
}

// elemRef represents a reference to an element on a given page/node.
type elemRef struct {
	page  *page
	node  *node
	index int
}

// isLeaf returns whether the ref is pointing at a leaf page/node.
func (r *elemRef) isLeaf() bool {
	if r.node != nil {
		return r.node.isLeaf
	}
	return (r.page.flags & leafPageFlag) != 0
}

// count returns the number of inodes or page elements.
func (r *elemRef) count() int {
	if r.node != nil {
		return len(r.node.inodes)
	}
	return int(r.page.count)
}
<commit_msg>Cursor.Seek validity is indicated by key being nil<commit_after>package bolt

import (
	"bytes"
	"sort"
)

// Cursor represents an iterator that can traverse over all key/value pairs in a bucket in sorted order.
// Cursors can be obtained from a transaction and are valid as long as the transaction is open.
type Cursor struct {
	bucket *Bucket
	stack  []elemRef
}

// Bucket returns the bucket that this cursor was created from.
func (c *Cursor) Bucket() *Bucket {
	return c.bucket
}

// First moves the cursor to the first item in the bucket and returns its key and value.
// If the bucket is empty then a nil key and value are returned.
func (c *Cursor) First() (key []byte, value []byte) {
	_assert(c.bucket.tx.db != nil, "tx closed")
	c.stack = c.stack[:0]
	p, n := c.bucket.pageNode(c.bucket.root)
	c.stack = append(c.stack, elemRef{page: p, node: n, index: 0})
	c.first()
	k, v, flags := c.keyValue()
	if (flags & uint32(bucketLeafFlag)) != 0 {
		return k, nil
	}
	return k, v

}

// Last moves the cursor to the last item in the bucket and returns its key and value.
// If the bucket is empty then a nil key and value are returned.
func (c *Cursor) Last() (key []byte, value []byte) {
	_assert(c.bucket.tx.db != nil, "tx closed")
	c.stack = c.stack[:0]
	p, n := c.bucket.pageNode(c.bucket.root)
	ref := elemRef{page: p, node: n}
	ref.index = ref.count() - 1
	c.stack = append(c.stack, ref)
	c.last()
	k, v, flags := c.keyValue()
	if (flags & uint32(bucketLeafFlag)) != 0 {
		return k, nil
	}
	return k, v
}

// Next moves the cursor to the next item in the bucket and returns its key and value.
// If the cursor is at the end of the bucket then a nil key and value are returned.
func (c *Cursor) Next() (key []byte, value []byte) {
	_assert(c.bucket.tx.db != nil, "tx closed")

	// Attempt to move over one element until we're successful.
	// Move up the stack as we hit the end of each page in our stack.
	for i := len(c.stack) - 1; i >= 0; i-- {
		elem := &c.stack[i]
		if elem.index < elem.count()-1 {
			elem.index++
			break
		}
		c.stack = c.stack[:i]
	}

	// If we've hit the end then return nil.
	if len(c.stack) == 0 {
		return nil, nil
	}

	// Move down the stack to find the first element of the first leaf under this branch.
	c.first()
	k, v, flags := c.keyValue()
	if (flags & uint32(bucketLeafFlag)) != 0 {
		return k, nil
	}
	return k, v
}

// Prev moves the cursor to the previous item in the bucket and returns its key and value.
// If the cursor is at the beginning of the bucket then a nil key and value are returned.
func (c *Cursor) Prev() (key []byte, value []byte) {
	_assert(c.bucket.tx.db != nil, "tx closed")

	// Attempt to move back one element until we're successful.
	// Move up the stack as we hit the beginning of each page in our stack.
	for i := len(c.stack) - 1; i >= 0; i-- {
		elem := &c.stack[i]
		if elem.index > 0 {
			elem.index--
			break
		}
		c.stack = c.stack[:i]
	}

	// If we've hit the end then return nil.
	if len(c.stack) == 0 {
		return nil, nil
	}

	// Move down the stack to find the last element of the last leaf under this branch.
	c.last()
	k, v, flags := c.keyValue()
	if (flags & uint32(bucketLeafFlag)) != 0 {
		return k, nil
	}
	return k, v
}

// Seek moves the cursor to a given key and returns it.
// If the key does not exist then the next key is used. If no keys
// follow, a nil key is returned.
func (c *Cursor) Seek(seek []byte) (key []byte, value []byte) {
	k, v, flags := c.seek(seek)
	if k == nil {
		return nil, nil
	} else if (flags & uint32(bucketLeafFlag)) != 0 {
		return k, nil
	}
	return k, v
}

// seek moves the cursor to a given key and returns it.
// If the key does not exist then the next key is used. If no keys
// follow, a nil value is returned.
func (c *Cursor) seek(seek []byte) (key []byte, value []byte, flags uint32) {
	_assert(c.bucket.tx.db != nil, "tx closed")

	// Start from root page/node and traverse to correct page.
	c.stack = c.stack[:0]
	c.search(seek, c.bucket.root)
	ref := &c.stack[len(c.stack)-1]

	// If the cursor is pointing to the end of page/node then return nil.
	if ref.index >= ref.count() {
		return nil, nil, 0
	}

	// If this is a bucket then return a nil value.
	return c.keyValue()
}

// first moves the cursor to the first leaf element under the last page in the stack.
func (c *Cursor) first() {
	for {
		// Exit when we hit a leaf page.
		ref := &c.stack[len(c.stack)-1]
		if ref.isLeaf() {
			break
		}

		// Keep adding pages pointing to the first element to the stack.
		var pgid pgid
		if ref.node != nil {
			pgid = ref.node.inodes[ref.index].pgid
		} else {
			pgid = ref.page.branchPageElement(uint16(ref.index)).pgid
		}
		p, n := c.bucket.pageNode(pgid)
		c.stack = append(c.stack, elemRef{page: p, node: n, index: 0})
	}
}

// last moves the cursor to the last leaf element under the last page in the stack.
func (c *Cursor) last() {
	for {
		// Exit when we hit a leaf page.
		ref := &c.stack[len(c.stack)-1]
		if ref.isLeaf() {
			break
		}

		// Keep adding pages pointing to the last element in the stack.
		var pgid pgid
		if ref.node != nil {
			pgid = ref.node.inodes[ref.index].pgid
		} else {
			pgid = ref.page.branchPageElement(uint16(ref.index)).pgid
		}
		p, n := c.bucket.pageNode(pgid)

		var nextRef = elemRef{page: p, node: n}
		nextRef.index = nextRef.count() - 1
		c.stack = append(c.stack, nextRef)
	}
}

// search recursively performs a binary search against a given page/node until it finds a given key.
func (c *Cursor) search(key []byte, pgid pgid) {
	p, n := c.bucket.pageNode(pgid)
	if p != nil {
		_assert((p.flags&(branchPageFlag|leafPageFlag)) != 0, "invalid page type: %d: %s", p.id, p.typ())
	}
	e := elemRef{page: p, node: n}
	c.stack = append(c.stack, e)

	// If we're on a leaf page/node then find the specific node.
	if e.isLeaf() {
		c.nsearch(key)
		return
	}

	if n != nil {
		c.searchNode(key, n)
		return
	}
	c.searchPage(key, p)
}

func (c *Cursor) searchNode(key []byte, n *node) {
	var exact bool
	index := sort.Search(len(n.inodes), func(i int) bool {
		// TODO(benbjohnson): Optimize this range search. It's a bit hacky right now.
		// sort.Search() finds the lowest index where f() != -1 but we need the highest index.
		ret := bytes.Compare(n.inodes[i].key, key)
		if ret == 0 {
			exact = true
		}
		return ret != -1
	})
	if !exact && index > 0 {
		index--
	}
	c.stack[len(c.stack)-1].index = index

	// Recursively search to the next page.
	c.search(key, n.inodes[index].pgid)
}

func (c *Cursor) searchPage(key []byte, p *page) {
	// Binary search for the correct range.
	inodes := p.branchPageElements()

	var exact bool
	index := sort.Search(int(p.count), func(i int) bool {
		// TODO(benbjohnson): Optimize this range search. It's a bit hacky right now.
		// sort.Search() finds the lowest index where f() != -1 but we need the highest index.
		ret := bytes.Compare(inodes[i].key(), key)
		if ret == 0 {
			exact = true
		}
		return ret != -1
	})
	if !exact && index > 0 {
		index--
	}
	c.stack[len(c.stack)-1].index = index

	// Recursively search to the next page.
	c.search(key, inodes[index].pgid)
}

// nsearch searches the leaf node on the top of the stack for a key.
func (c *Cursor) nsearch(key []byte) {
	e := &c.stack[len(c.stack)-1]
	p, n := e.page, e.node

	// If we have a node then search its inodes.
	if n != nil {
		index := sort.Search(len(n.inodes), func(i int) bool {
			return bytes.Compare(n.inodes[i].key, key) != -1
		})
		e.index = index
		return
	}

	// If we have a page then search its leaf elements.
	inodes := p.leafPageElements()
	index := sort.Search(int(p.count), func(i int) bool {
		return bytes.Compare(inodes[i].key(), key) != -1
	})
	e.index = index
}

// keyValue returns the key and value of the current leaf element.
func (c *Cursor) keyValue() ([]byte, []byte, uint32) {
	ref := &c.stack[len(c.stack)-1]
	if ref.count() == 0 || ref.index >= ref.count() {
		return nil, nil, 0
	}

	// Retrieve value from node.
	if ref.node != nil {
		inode := &ref.node.inodes[ref.index]
		return inode.key, inode.value, inode.flags
	}

	// Or retrieve value from page.
	elem := ref.page.leafPageElement(uint16(ref.index))
	return elem.key(), elem.value(), elem.flags
}

// node returns the node that the cursor is currently positioned on.
func (c *Cursor) node() *node {
	_assert(len(c.stack) > 0, "accessing a node with a zero-length cursor stack")

	// If the top of the stack is a leaf node then just return it.
	if ref := &c.stack[len(c.stack)-1]; ref.node != nil && ref.isLeaf() {
		return ref.node
	}

	// Start from root and traverse down the hierarchy.
	var n = c.stack[0].node
	if n == nil {
		n = c.bucket.node(c.stack[0].page.id, nil)
	}
	for _, ref := range c.stack[:len(c.stack)-1] {
		_assert(!n.isLeaf, "expected branch node")
		n = n.childAt(int(ref.index))
	}
	_assert(n.isLeaf, "expected leaf node")
	return n
}

// elemRef represents a reference to an element on a given page/node.
type elemRef struct {
	page  *page
	node  *node
	index int
}

// isLeaf returns whether the ref is pointing at a leaf page/node.
func (r *elemRef) isLeaf() bool {
	if r.node != nil {
		return r.node.isLeaf
	}
	return (r.page.flags & leafPageFlag) != 0
}

// count returns the number of inodes or page elements.
func (r *elemRef) count() int {
	if r.node != nil {
		return len(r.node.inodes)
	}
	return int(r.page.count)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"net/http"
	"os"

	"github.com/dongri/line-bot-sdk-go/linebot"
)

var botClient *linebot.Client

func main() {
	channelAccessToken := os.Getenv("LINE_CHANNEL_ACCESSTOKEN")
	channelSecret := os.Getenv("LINE_CHANNEL_SECRET")

	botClient = linebot.NewClient(channelAccessToken)
	botClient.SetChannelSecret(channelSecret)

	// EventHandler
	var myEvent linebot.EventHandler = NewEventHandler()
	botClient.SetEventHandler(myEvent)

	http.HandleFunc("/", indexHandler)
	http.Handle("/callback", linebot.Middleware(http.HandlerFunc(callbackHandler)))
	port := os.Getenv("PORT")
	if len(port) == 0 {
		port = "3000"
	}
	addr := fmt.Sprintf(":%s", port)
	http.ListenAndServe(addr, nil)
}

func indexHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Hello, Bot")
}

func callbackHandler(w http.ResponseWriter, r *http.Request) {
	log.Print("=== callback ===")
}

// BotEventHandler ...
type BotEventHandler struct{}

// NewEventHandler ...
func NewEventHandler() *BotEventHandler {
	return &BotEventHandler{}
}

// OnFollowEvent ...
func (be *BotEventHandler) OnFollowEvent(replyToken string) {
	message := linebot.NewTextMessage("Hello!")
	result, err := botClient.ReplyMessage(replyToken, message)
	fmt.Println(result)
	fmt.Println(err)
}

// OnUnFollowEvent ...
func (be *BotEventHandler) OnUnFollowEvent() {
	log.Print("=== ブロックされた ===")
}

// OnJoinEvent ...
func (be *BotEventHandler) OnJoinEvent(replyToken string) {
	message := linebot.NewTextMessage("Room, Group 招待ありがとう!")
	result, err := botClient.ReplyMessage(replyToken, message)
	fmt.Println(result)
	fmt.Println(err)
}

// OnLeaveEvent ...
func (be *BotEventHandler) OnLeaveEvent() {
	log.Print("=== Groupから蹴られた ===")
}

// OnPostbackEvent ...
func (be *BotEventHandler) OnPostbackEvent(replyToken, postbackData string) {
	message := linebot.NewTextMessage("「" + postbackData + "」を選択したね！")
	result, err := botClient.ReplyMessage(replyToken, message)
	fmt.Println(result)
	fmt.Println(err)
}

// OnBeaconEvent ...
func (be *BotEventHandler) OnBeaconEvent(replyToken, beaconHwid, beaconYype string) {
	log.Print("=== Beacon Event ===")
}

// OnTextMessage ...
func (be *BotEventHandler) OnTextMessage(replyToken, text string) {
	if text == "sample1" {
		templateLabel := "Go"
		templateText := "Hello, Golang!"
		thumbnailImageURL := "https://dl.dropboxusercontent.com/u/358152/linebot/resource/gopher.png"
		actionLabel := "Go to golang.org"
		actionURI := "https://golang.org"
		template := linebot.NewButtonsTemplate(
			thumbnailImageURL, templateLabel, templateText,
			linebot.NewTemplateURIAction(actionLabel, actionURI),
			linebot.NewTemplatePostbackAction("hello postback", "hello こんにちは", "必須じゃない？！"),
			linebot.NewTemplateMessageAction("hello message", "hello こんにちは2"),
		)
		altText := "Go template"
		message := linebot.NewTemplateMessage(altText, template)
		result, err := botClient.ReplyMessage(replyToken, message)
		fmt.Println(result)
		fmt.Println(err)
	} else if text == "sample2" {
		template := linebot.NewConfirmTemplate(
			"Do it?",
			linebot.NewTemplateMessageAction("Yes", "Yes!"),
			linebot.NewTemplateMessageAction("No", "No!"),
		)
		altText := "Confirm template"
		message := linebot.NewTemplateMessage(altText, template)
		result, err := botClient.ReplyMessage(replyToken, message)
		fmt.Println(result)
		fmt.Println(err)
	} else if text == "sample3" {
		baseURL := "https://dl.dropboxusercontent.com/u/358152/linebot/resource"
		altText := "Golang"
		baseSizeWidth := 520
		baseSizeHeight := 520
		message := linebot.NewImagemapMessage(baseURL, altText, baseSizeWidth, baseSizeHeight,
			linebot.NewImagemapURIAction("https://golang.org", *linebot.NewImagemapArea(0, 0, 520, 520)),
		)
		result, err := botClient.ReplyMessage(replyToken, message)
		fmt.Println(result)
		fmt.Println(err)
	} else if text == "sample4" {
		originalContentURL := "https://dl.dropboxusercontent.com/u/358152/linebot/resource/ok.m4a"
		duration := 1000
		message := linebot.NewAudioMessage(originalContentURL, duration)
		result, err := botClient.ReplyMessage(replyToken, message)
		fmt.Println(result)
		fmt.Println(err)
	} else {
		message := linebot.NewTextMessage(text)
		result, err := botClient.ReplyMessage(replyToken, message)
		fmt.Println(result)
		fmt.Println(err)
	}
}

// OnImageMessage ...
func (be *BotEventHandler) OnImageMessage(replyToken, id string) {
	originalContentURL := "https://dl.dropboxusercontent.com/u/358152/linebot/resource/gohper.jpg"
	previewImageURL := "https://dl.dropboxusercontent.com/u/358152/linebot/resource/gohper.jpg"
	message := linebot.NewImageMessage(originalContentURL, previewImageURL)
	result, err := botClient.ReplyMessage(replyToken, message)
	fmt.Println(result)
	fmt.Println(err)
}

// OnVideoMessage ...
func (be *BotEventHandler) OnVideoMessage(replyToken, id string) {
	originalContentURL := "https://dl.dropboxusercontent.com/u/358152/linebot/resource/video-original.mp4"
	previewImageURL := "https://dl.dropboxusercontent.com/u/358152/linebot/resource/video-preview.png"
	message := linebot.NewVideoMessage(originalContentURL, previewImageURL)
	result, err := botClient.ReplyMessage(replyToken, message)
	fmt.Println(result)
	fmt.Println(err)
}

// OnAudioMessage ...
func (be *BotEventHandler) OnAudioMessage(replyToken, id string) {
	originalContentURL := "https://dl.dropboxusercontent.com/u/358152/linebot/resource/ok.m4a"
	duration := 1000
	message := linebot.NewAudioMessage(originalContentURL, duration)
	result, err := botClient.ReplyMessage(replyToken, message)
	fmt.Println(result)
	fmt.Println(err)
}

// OnLocationMessage ...
func (be *BotEventHandler) OnLocationMessage(replyToken string, latitude, longitude float64) {
	title := "Disney Resort"
	address := "〒279-0031 千葉県浦安市舞浜１−１"
	lat := 35.632211
	lon := 139.881234
	message := linebot.NewLocationMessage(title, address, lat, lon)
	result, err := botClient.ReplyMessage(replyToken, message)
	fmt.Println(result)
	fmt.Println(err)
}

// OnStickerMessage ...
func (be *BotEventHandler) OnStickerMessage(replyToken, stickerID string) {
	message := linebot.NewStickerMessage("1", "1")
	result, err := botClient.ReplyMessage(replyToken, message)
	fmt.Println(result)
	fmt.Println(err)
}
<commit_msg>Fix message<commit_after>package main

import (
	"fmt"
	"log"
	"net/http"
	"os"

	"github.com/dongri/line-bot-sdk-go/linebot"
)

var botClient *linebot.Client

func main() {
	channelAccessToken := os.Getenv("LINE_CHANNEL_ACCESSTOKEN")
	channelSecret := os.Getenv("LINE_CHANNEL_SECRET")

	botClient = linebot.NewClient(channelAccessToken)
	botClient.SetChannelSecret(channelSecret)

	// EventHandler
	var myEvent linebot.EventHandler = NewEventHandler()
	botClient.SetEventHandler(myEvent)

	http.HandleFunc("/", indexHandler)
	http.Handle("/callback", linebot.Middleware(http.HandlerFunc(callbackHandler)))
	port := os.Getenv("PORT")
	if len(port) == 0 {
		port = "3000"
	}
	addr := fmt.Sprintf(":%s", port)
	http.ListenAndServe(addr, nil)
}

func indexHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Hello, Bot")
}

func callbackHandler(w http.ResponseWriter, r *http.Request) {
	log.Print("=== callback ===")
}

// BotEventHandler ...
type BotEventHandler struct{}

// NewEventHandler ...
func NewEventHandler() *BotEventHandler {
	return &BotEventHandler{}
}

// OnFollowEvent ...
func (be *BotEventHandler) OnFollowEvent(replyToken string) {
	message := linebot.NewTextMessage("Hello!")
	result, err := botClient.ReplyMessage(replyToken, message)
	fmt.Println(result)
	fmt.Println(err)
}

// OnUnFollowEvent ...
func (be *BotEventHandler) OnUnFollowEvent() {
	log.Print("=== ブロックされた ===")
}

// OnJoinEvent ...
func (be *BotEventHandler) OnJoinEvent(replyToken string) {
	message := linebot.NewTextMessage("Room, Group 招待ありがとう!")
	result, err := botClient.ReplyMessage(replyToken, message)
	fmt.Println(result)
	fmt.Println(err)
}

// OnLeaveEvent ...
func (be *BotEventHandler) OnLeaveEvent() {
	log.Print("=== Groupから蹴られた ===")
}

// OnPostbackEvent ...
func (be *BotEventHandler) OnPostbackEvent(replyToken, postbackData string) {
	message := linebot.NewTextMessage("「" + postbackData + "」を選択したね！")
	result, err := botClient.ReplyMessage(replyToken, message)
	fmt.Println(result)
	fmt.Println(err)
}

// OnBeaconEvent ...
func (be *BotEventHandler) OnBeaconEvent(replyToken, beaconHwid, beaconYype string) {
	log.Print("=== Beacon Event ===")
}

// OnTextMessage ...
func (be *BotEventHandler) OnTextMessage(replyToken, text string) {
	if text == "sample1" {
		templateLabel := "Go"
		templateText := "Hello, Golang!"
		thumbnailImageURL := "https://dl.dropboxusercontent.com/u/358152/linebot/resource/gopher.png"
		actionLabel := "Go to golang.org"
		actionURI := "https://golang.org"
		template := linebot.NewButtonsTemplate(
			thumbnailImageURL, templateLabel, templateText,
			linebot.NewTemplateURIAction(actionLabel, actionURI),
			linebot.NewTemplatePostbackAction("hello postback", "hello こんにちは", "必須じゃない？！"),
			linebot.NewTemplateMessageAction("hello message", "hello こんにちは2"),
		)
		altText := "Go template"
		message := linebot.NewTemplateMessage(altText, template)
		result, err := botClient.ReplyMessage(replyToken, message)
		fmt.Println(result)
		fmt.Println(err)
	} else if text == "sample2" {
		template := linebot.NewConfirmTemplate(
			"Do it?",
			linebot.NewTemplateMessageAction("Yes", "Yes!"),
			linebot.NewTemplateMessageAction("No", "No!"),
		)
		altText := "Confirm template"
		message := linebot.NewTemplateMessage(altText, template)
		result, err := botClient.ReplyMessage(replyToken, message)
		fmt.Println(result)
		fmt.Println(err)
	} else if text == "sample3" {
		baseURL := "https://dl.dropboxusercontent.com/u/358152/linebot/resource"
		altText := "Golang"
		baseSizeWidth := 520
		baseSizeHeight := 520
		message := linebot.NewImagemapMessage(baseURL, altText, baseSizeWidth, baseSizeHeight,
			linebot.NewImagemapURIAction("https://golang.org", *linebot.NewImagemapArea(0, 0, 520, 520)),
		)
		result, err := botClient.ReplyMessage(replyToken, message)
		fmt.Println(result)
		fmt.Println(err)
	} else if text == "sample4" {
		originalContentURL := "https://dl.dropboxusercontent.com/u/358152/linebot/resource/ok.m4a"
		duration := 1000
		message := linebot.NewAudioMessage(originalContentURL, duration)
		result, err := botClient.ReplyMessage(replyToken, message)
		fmt.Println(result)
		fmt.Println(err)
	} else {
		message := linebot.NewTextMessage(text + "じゃねぇよ！")
		result, err := botClient.ReplyMessage(replyToken, message)
		fmt.Println(result)
		fmt.Println(err)
	}
}

// OnImageMessage ...
func (be *BotEventHandler) OnImageMessage(replyToken, id string) {
	originalContentURL := "https://dl.dropboxusercontent.com/u/358152/linebot/resource/gohper.jpg"
	previewImageURL := "https://dl.dropboxusercontent.com/u/358152/linebot/resource/gohper.jpg"
	message := linebot.NewImageMessage(originalContentURL, previewImageURL)
	result, err := botClient.ReplyMessage(replyToken, message)
	fmt.Println(result)
	fmt.Println(err)
}

// OnVideoMessage ...
func (be *BotEventHandler) OnVideoMessage(replyToken, id string) {
	originalContentURL := "https://dl.dropboxusercontent.com/u/358152/linebot/resource/video-original.mp4"
	previewImageURL := "https://dl.dropboxusercontent.com/u/358152/linebot/resource/video-preview.png"
	message := linebot.NewVideoMessage(originalContentURL, previewImageURL)
	result, err := botClient.ReplyMessage(replyToken, message)
	fmt.Println(result)
	fmt.Println(err)
}

// OnAudioMessage ...
func (be *BotEventHandler) OnAudioMessage(replyToken, id string) {
	originalContentURL := "https://dl.dropboxusercontent.com/u/358152/linebot/resource/ok.m4a"
	duration := 1000
	message := linebot.NewAudioMessage(originalContentURL, duration)
	result, err := botClient.ReplyMessage(replyToken, message)
	fmt.Println(result)
	fmt.Println(err)
}

// OnLocationMessage ...
func (be *BotEventHandler) OnLocationMessage(replyToken string, latitude, longitude float64) {
	title := "Disney Resort"
	address := "〒279-0031 千葉県浦安市舞浜１−１"
	lat := 35.632211
	lon := 139.881234
	message := linebot.NewLocationMessage(title, address, lat, lon)
	result, err := botClient.ReplyMessage(replyToken, message)
	fmt.Println(result)
	fmt.Println(err)
}

// OnStickerMessage ...
func (be *BotEventHandler) OnStickerMessage(replyToken, stickerID string) {
	message := linebot.NewStickerMessage("1", "1")
	result, err := botClient.ReplyMessage(replyToken, message)
	fmt.Println(result)
	fmt.Println(err)
}
<|endoftext|>