<commit_before>package dnsr

var root = `
;       This file holds the information on root name servers needed to
;       initialize cache of Internet domain name servers
;       (e.g. reference this file in the "cache  .  <file>"
;       configuration file of BIND domain name servers).
;
;       This file is made available by InterNIC
;       under anonymous FTP as
;           file                /domain/named.cache
;           on server           FTP.INTERNIC.NET
;       -OR-                    RS.INTERNIC.NET
;
;       last update:    April 11, 2017
;       related version of root zone:   2017041101
;
; formerly NS.INTERNIC.NET
;
.                        3600000      NS    A.ROOT-SERVERS.NET.
A.ROOT-SERVERS.NET.      3600000      A     198.41.0.4
A.ROOT-SERVERS.NET.      3600000      AAAA  2001:503:ba3e::2:30
;
; FORMERLY NS1.ISI.EDU
;
.                        3600000      NS    B.ROOT-SERVERS.NET.
B.ROOT-SERVERS.NET.      3600000      A     192.228.79.201
B.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:84::b
;
; FORMERLY C.PSI.NET
;
.                        3600000      NS    C.ROOT-SERVERS.NET.
C.ROOT-SERVERS.NET.      3600000      A     192.33.4.12
C.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:2::c
;
; FORMERLY TERP.UMD.EDU
;
.                        3600000      NS    D.ROOT-SERVERS.NET.
D.ROOT-SERVERS.NET.      3600000      A     199.7.91.13
D.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:2d::d
;
; FORMERLY NS.NASA.GOV
;
.                        3600000      NS    E.ROOT-SERVERS.NET.
E.ROOT-SERVERS.NET.      3600000      A     192.203.230.10
E.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:a8::e
;
; FORMERLY NS.ISC.ORG
;
.                        3600000      NS    F.ROOT-SERVERS.NET.
F.ROOT-SERVERS.NET.      3600000      A     192.5.5.241
F.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:2f::f
;
; FORMERLY NS.NIC.DDN.MIL
;
.                        3600000      NS    G.ROOT-SERVERS.NET.
G.ROOT-SERVERS.NET.      3600000      A     192.112.36.4
G.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:12::d0d
;
; FORMERLY AOS.ARL.ARMY.MIL
;
.                        3600000      NS    H.ROOT-SERVERS.NET.
H.ROOT-SERVERS.NET.      3600000      A     198.97.190.53
H.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:1::53
;
; FORMERLY NIC.NORDU.NET
;
.                        3600000      NS    I.ROOT-SERVERS.NET.
I.ROOT-SERVERS.NET.      3600000      A     192.36.148.17
I.ROOT-SERVERS.NET.      3600000      AAAA  2001:7fe::53
;
; OPERATED BY VERISIGN, INC.
;
.                        3600000      NS    J.ROOT-SERVERS.NET.
J.ROOT-SERVERS.NET.      3600000      A     192.58.128.30
J.ROOT-SERVERS.NET.      3600000      AAAA  2001:503:c27::2:30
;
; OPERATED BY RIPE NCC
;
.                        3600000      NS    K.ROOT-SERVERS.NET.
K.ROOT-SERVERS.NET.      3600000      A     193.0.14.129
K.ROOT-SERVERS.NET.      3600000      AAAA  2001:7fd::1
;
; OPERATED BY ICANN
;
.                        3600000      NS    L.ROOT-SERVERS.NET.
L.ROOT-SERVERS.NET.      3600000      A     199.7.83.42
L.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:9f::42
;
; OPERATED BY WIDE
;
.                        3600000      NS    M.ROOT-SERVERS.NET.
M.ROOT-SERVERS.NET.      3600000      A     202.12.27.33
M.ROOT-SERVERS.NET.      3600000      AAAA  2001:dc3::35
; End of file
`
<commit_msg>autopull: 2017-06-01T23:30:19Z<commit_after>package dnsr

var root = `
;       This file holds the information on root name servers needed to
;       initialize cache of Internet domain name servers
;       (e.g. reference this file in the "cache  .  <file>"
;       configuration file of BIND domain name servers).
;
;       This file is made available by InterNIC
;       under anonymous FTP as
;           file                /domain/named.cache
;           on server           FTP.INTERNIC.NET
;       -OR-                    RS.INTERNIC.NET
;
;       last update:    June 01, 2017
;       related version of root zone:   2017060102
;
; formerly NS.INTERNIC.NET
;
.                        3600000      NS    A.ROOT-SERVERS.NET.
A.ROOT-SERVERS.NET.      3600000      A     198.41.0.4
A.ROOT-SERVERS.NET.      3600000      AAAA  2001:503:ba3e::2:30
;
; FORMERLY NS1.ISI.EDU
;
.                        3600000      NS    B.ROOT-SERVERS.NET.
B.ROOT-SERVERS.NET.      3600000      A     192.228.79.201
B.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:200::b
;
; FORMERLY C.PSI.NET
;
.                        3600000      NS    C.ROOT-SERVERS.NET.
C.ROOT-SERVERS.NET.      3600000      A     192.33.4.12
C.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:2::c
;
; FORMERLY TERP.UMD.EDU
;
.                        3600000      NS    D.ROOT-SERVERS.NET.
D.ROOT-SERVERS.NET.      3600000      A     199.7.91.13
D.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:2d::d
;
; FORMERLY NS.NASA.GOV
;
.                        3600000      NS    E.ROOT-SERVERS.NET.
E.ROOT-SERVERS.NET.      3600000      A     192.203.230.10
E.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:a8::e
;
; FORMERLY NS.ISC.ORG
;
.                        3600000      NS    F.ROOT-SERVERS.NET.
F.ROOT-SERVERS.NET.      3600000      A     192.5.5.241
F.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:2f::f
;
; FORMERLY NS.NIC.DDN.MIL
;
.                        3600000      NS    G.ROOT-SERVERS.NET.
G.ROOT-SERVERS.NET.      3600000      A     192.112.36.4
G.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:12::d0d
;
; FORMERLY AOS.ARL.ARMY.MIL
;
.                        3600000      NS    H.ROOT-SERVERS.NET.
H.ROOT-SERVERS.NET.      3600000      A     198.97.190.53
H.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:1::53
;
; FORMERLY NIC.NORDU.NET
;
.                        3600000      NS    I.ROOT-SERVERS.NET.
I.ROOT-SERVERS.NET.      3600000      A     192.36.148.17
I.ROOT-SERVERS.NET.      3600000      AAAA  2001:7fe::53
;
; OPERATED BY VERISIGN, INC.
;
.                        3600000      NS    J.ROOT-SERVERS.NET.
J.ROOT-SERVERS.NET.      3600000      A     192.58.128.30
J.ROOT-SERVERS.NET.      3600000      AAAA  2001:503:c27::2:30
;
; OPERATED BY RIPE NCC
;
.                        3600000      NS    K.ROOT-SERVERS.NET.
K.ROOT-SERVERS.NET.      3600000      A     193.0.14.129
K.ROOT-SERVERS.NET.      3600000      AAAA  2001:7fd::1
;
; OPERATED BY ICANN
;
.                        3600000      NS    L.ROOT-SERVERS.NET.
L.ROOT-SERVERS.NET.      3600000      A     199.7.83.42
L.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:9f::42
;
; OPERATED BY WIDE
;
.                        3600000      NS    M.ROOT-SERVERS.NET.
M.ROOT-SERVERS.NET.      3600000      A     202.12.27.33
M.ROOT-SERVERS.NET.      3600000      AAAA  2001:dc3::35
; End of file
`
<|endoftext|>


<commit_before>package runc

import (
	"context"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"strconv"
	"syscall"
	"time"

	specs "github.com/opencontainers/runtime-spec/specs-go"
)

// Format is the type of log formatting options avaliable
type Format string

const (
	none Format = ""
	JSON Format = "json"
	Text Format = "text"
	// DefaultCommand is the default command for Runc
	DefaultCommand string = "runc"
)

// Runc is the client to the runc cli
type Runc struct {
	//If command is empty, DefaultCommand is used
	Command      string
	Root         string
	Debug        bool
	Log          string
	LogFormat    Format
	PdeathSignal syscall.Signal
}

// List returns all containers created inside the provided runc root directory
func (r *Runc) List(context context.Context) ([]*Container, error) {
	data, err := r.command(context, "list", "--format=json").Output()
	if err != nil {
		return nil, err
	}
	var out []*Container
	if err := json.Unmarshal(data, &out); err != nil {
		return nil, err
	}
	return out, nil
}

// State returns the state for the container provided by id
func (r *Runc) State(context context.Context, id string) (*Container, error) {
	data, err := r.command(context, "state", id).CombinedOutput()
	if err != nil {
		return nil, fmt.Errorf("%s: %s", err, data)
	}
	var c Container
	if err := json.Unmarshal(data, &c); err != nil {
		return nil, err
	}
	return &c, nil
}

type CreateOpts struct {
	IO
	// PidFile is a path to where a pid file should be created
	PidFile       string
	ConsoleSocket string
	Detach        bool
	NoPivot       bool
	NoNewKeyring  bool
}

type IO struct {
	Stdin  io.Reader
	Stdout io.Writer
	Stderr io.Writer
}

func (i *IO) Close() error {
	var err error
	for _, v := range []interface{}{
		i.Stdin,
		i.Stderr,
		i.Stdout,
	} {
		if v != nil {
			if c, ok := v.(io.Closer); ok {
				if cerr := c.Close(); err == nil {
					err = cerr
				}
			}
		}
	}
	return err
}

func (o IO) setSTDIO(cmd *exec.Cmd) {
	cmd.Stdin = o.Stdin
	cmd.Stdout = o.Stdout
	cmd.Stderr = o.Stderr
}

func (o *CreateOpts) args() (out []string) {
	if o.PidFile != "" {
		out = append(out, "--pid-file", o.PidFile)
	}
	if o.ConsoleSocket != "" {
		out = append(out, "--console-socket", o.ConsoleSocket)
	}
	if o.NoPivot {
		out = append(out, "--no-pivot")
	}
	if o.NoNewKeyring {
		out = append(out, "--no-new-keyring")
	}
	if o.Detach {
		out = append(out, "--detach")
	}
	return out
}

// Create creates a new container and returns its pid if it was created successfully
func (r *Runc) Create(context context.Context, id, bundle string, opts *CreateOpts) error {
	args := []string{"create", "--bundle", bundle}
	if opts != nil {
		args = append(args, opts.args()...)
	}
	cmd := r.command(context, append(args, id)...)
	if opts != nil {
		opts.setSTDIO(cmd)
	}
	return runOrError(cmd)
}

// Start will start an already created container
func (r *Runc) Start(context context.Context, id string) error {
	return runOrError(r.command(context, "start", id))
}

type ExecOpts struct {
	IO
	PidFile       string
	Uid           int
	Gid           int
	Cwd           string
	Tty           bool
	ConsoleSocket string
	Detach        bool
}

func (o *ExecOpts) args() (out []string) {
	out = append(out, "--user", fmt.Sprintf("%d:%d", o.Uid, o.Gid))
	if o.Tty {
		out = append(out, "--tty")
	}
	if o.ConsoleSocket != "" {
		out = append(out, "--console", o.ConsoleSocket)
	}
	if o.Cwd != "" {
		out = append(out, "--cwd", o.Cwd)
	}
	if o.Detach {
		out = append(out, "--detach")
	}
	if o.PidFile != "" {
		out = append(out, "--pid-file", o.PidFile)
	}
	return out
}

// Exec executres and additional process inside the container based on a full
// OCI Process specification
func (r *Runc) Exec(context context.Context, id string, spec specs.Process, opts *ExecOpts) error {
	f, err := ioutil.TempFile("", "-process")
	if err != nil {
		return err
	}
	defer os.Remove(f.Name())
	err = json.NewEncoder(f).Encode(spec)
	f.Close()
	if err != nil {
		return err
	}
	args := []string{"exec", "--process", f.Name()}
	if opts != nil {
		args = append(args, opts.args()...)
	}
	cmd := r.command(context, append(args, id)...)
	if opts != nil {
		opts.setSTDIO(cmd)
	}
	return runOrError(cmd)
}

// Run runs the create, start, delete lifecycle of the container
// and returns its exit status after it has exited
func (r *Runc) Run(context context.Context, id, bundle string, opts *CreateOpts) (int, error) {
	args := []string{"run", "--bundle", bundle}
	if opts != nil {
		args = append(args, opts.args()...)
	}
	cmd := r.command(context, append(args, id)...)
	if opts != nil {
		opts.setSTDIO(cmd)
	}
	if err := cmd.Start(); err != nil {
		return -1, err
	}
	status, err := cmd.Process.Wait()
	if err != nil {
		return -1, err
	}
	return status.Sys().(syscall.WaitStatus).ExitStatus(), nil
}

// Delete deletes the container
func (r *Runc) Delete(context context.Context, id string) error {
	return runOrError(r.command(context, "delete", id))
}

// KillOpts specifies options for killing a container and its processes
type KillOpts struct {
	All bool
}

func (o *KillOpts) args() (out []string) {
	if o.All {
		out = append(out, "--all")
	}
	return out
}

// Kill sends the specified signal to the container
func (r *Runc) Kill(context context.Context, id string, sig int, opts *KillOpts) error {
	args := []string{
		"kill",
	}
	if opts != nil {
		args = append(args, opts.args()...)
	}
	return runOrError(r.command(context, append(args, id, strconv.Itoa(sig))...))
}

// Stats return the stats for a container like cpu, memory, and io
func (r *Runc) Stats(context context.Context, id string) (*Stats, error) {
	cmd := r.command(context, "events", "--stats", id)
	rd, err := cmd.StdoutPipe()
	if err != nil {
		return nil, err
	}
	defer func() {
		rd.Close()
		cmd.Wait()
	}()
	if err := cmd.Start(); err != nil {
		return nil, err
	}
	var e Event
	if err := json.NewDecoder(rd).Decode(&e); err != nil {
		return nil, err
	}
	return e.Stats, nil
}

// Events returns an event stream from runc for a container with stats and OOM notifications
func (r *Runc) Events(context context.Context, id string, interval time.Duration) (chan *Event, error) {
	cmd := r.command(context, "events", fmt.Sprintf("--interval=%ds", int(interval.Seconds())), id)
	rd, err := cmd.StdoutPipe()
	if err != nil {
		return nil, err
	}
	if err := cmd.Start(); err != nil {
		rd.Close()
		return nil, err
	}
	var (
		dec = json.NewDecoder(rd)
		c   = make(chan *Event, 128)
	)
	go func() {
		defer func() {
			close(c)
			rd.Close()
			cmd.Wait()
		}()
		for {
			var e Event
			if err := dec.Decode(&e); err != nil {
				if err == io.EOF {
					return
				}
				e = Event{
					Type: "error",
					Err:  err,
				}
			}
			c <- &e
		}
	}()
	return c, nil
}

// Pause the container with the provided id
func (r *Runc) Pause(context context.Context, id string) error {
	return runOrError(r.command(context, "pause", id))
}

// Resume the container with the provided id
func (r *Runc) Resume(context context.Context, id string) error {
	return runOrError(r.command(context, "resume", id))
}

// Ps lists all the processes inside the container returning their pids
func (r *Runc) Ps(context context.Context, id string) ([]int, error) {
	data, err := r.command(context, "ps", "--format", "json", id).CombinedOutput()
	if err != nil {
		return nil, fmt.Errorf("%s: %s", err, data)
	}
	var pids []int
	if err := json.Unmarshal(data, &pids); err != nil {
		return nil, err
	}
	return pids, nil
}

func (r *Runc) args() (out []string) {
	if r.Root != "" {
		out = append(out, "--root", r.Root)
	}
	if r.Debug {
		out = append(out, "--debug")
	}
	if r.Log != "" {
		out = append(out, "--log", r.Log)
	}
	if r.LogFormat != none {
		out = append(out, "--log-format", string(r.LogFormat))
	}
	return out
}

func (r *Runc) command(context context.Context, args ...string) *exec.Cmd {
	command := r.Command
	if command == "" {
		command = DefaultCommand
	}
	cmd := exec.CommandContext(context, command, append(r.args(), args...)...)
	if r.PdeathSignal != 0 {
		cmd.SysProcAttr = &syscall.SysProcAttr{
			Pdeathsig: r.PdeathSignal,
		}
	}
	return cmd
}
<commit_msg>fix support for `exec --console-socket`<commit_after>package runc

import (
	"context"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"strconv"
	"syscall"
	"time"

	specs "github.com/opencontainers/runtime-spec/specs-go"
)

// Format is the type of log formatting options avaliable
type Format string

const (
	none Format = ""
	JSON Format = "json"
	Text Format = "text"
	// DefaultCommand is the default command for Runc
	DefaultCommand string = "runc"
)

// Runc is the client to the runc cli
type Runc struct {
	//If command is empty, DefaultCommand is used
	Command      string
	Root         string
	Debug        bool
	Log          string
	LogFormat    Format
	PdeathSignal syscall.Signal
}

// List returns all containers created inside the provided runc root directory
func (r *Runc) List(context context.Context) ([]*Container, error) {
	data, err := r.command(context, "list", "--format=json").Output()
	if err != nil {
		return nil, err
	}
	var out []*Container
	if err := json.Unmarshal(data, &out); err != nil {
		return nil, err
	}
	return out, nil
}

// State returns the state for the container provided by id
func (r *Runc) State(context context.Context, id string) (*Container, error) {
	data, err := r.command(context, "state", id).CombinedOutput()
	if err != nil {
		return nil, fmt.Errorf("%s: %s", err, data)
	}
	var c Container
	if err := json.Unmarshal(data, &c); err != nil {
		return nil, err
	}
	return &c, nil
}

type CreateOpts struct {
	IO
	// PidFile is a path to where a pid file should be created
	PidFile       string
	ConsoleSocket string
	Detach        bool
	NoPivot       bool
	NoNewKeyring  bool
}

type IO struct {
	Stdin  io.Reader
	Stdout io.Writer
	Stderr io.Writer
}

func (i *IO) Close() error {
	var err error
	for _, v := range []interface{}{
		i.Stdin,
		i.Stderr,
		i.Stdout,
	} {
		if v != nil {
			if c, ok := v.(io.Closer); ok {
				if cerr := c.Close(); err == nil {
					err = cerr
				}
			}
		}
	}
	return err
}

func (o IO) setSTDIO(cmd *exec.Cmd) {
	cmd.Stdin = o.Stdin
	cmd.Stdout = o.Stdout
	cmd.Stderr = o.Stderr
}

func (o *CreateOpts) args() (out []string) {
	if o.PidFile != "" {
		out = append(out, "--pid-file", o.PidFile)
	}
	if o.ConsoleSocket != "" {
		out = append(out, "--console-socket", o.ConsoleSocket)
	}
	if o.NoPivot {
		out = append(out, "--no-pivot")
	}
	if o.NoNewKeyring {
		out = append(out, "--no-new-keyring")
	}
	if o.Detach {
		out = append(out, "--detach")
	}
	return out
}

// Create creates a new container and returns its pid if it was created successfully
func (r *Runc) Create(context context.Context, id, bundle string, opts *CreateOpts) error {
	args := []string{"create", "--bundle", bundle}
	if opts != nil {
		args = append(args, opts.args()...)
	}
	cmd := r.command(context, append(args, id)...)
	if opts != nil {
		opts.setSTDIO(cmd)
	}
	return runOrError(cmd)
}

// Start will start an already created container
func (r *Runc) Start(context context.Context, id string) error {
	return runOrError(r.command(context, "start", id))
}

type ExecOpts struct {
	IO
	PidFile       string
	Uid           int
	Gid           int
	Cwd           string
	Tty           bool
	ConsoleSocket string
	Detach        bool
}

func (o *ExecOpts) args() (out []string) {
	out = append(out, "--user", fmt.Sprintf("%d:%d", o.Uid, o.Gid))
	if o.Tty {
		out = append(out, "--tty")
	}
	if o.ConsoleSocket != "" {
		out = append(out, "--console-socket", o.ConsoleSocket)
	}
	if o.Cwd != "" {
		out = append(out, "--cwd", o.Cwd)
	}
	if o.Detach {
		out = append(out, "--detach")
	}
	if o.PidFile != "" {
		out = append(out, "--pid-file", o.PidFile)
	}
	return out
}

// Exec executres and additional process inside the container based on a full
// OCI Process specification
func (r *Runc) Exec(context context.Context, id string, spec specs.Process, opts *ExecOpts) error {
	f, err := ioutil.TempFile("", "-process")
	if err != nil {
		return err
	}
	defer os.Remove(f.Name())
	err = json.NewEncoder(f).Encode(spec)
	f.Close()
	if err != nil {
		return err
	}
	args := []string{"exec", "--process", f.Name()}
	if opts != nil {
		args = append(args, opts.args()...)
	}
	cmd := r.command(context, append(args, id)...)
	if opts != nil {
		opts.setSTDIO(cmd)
	}
	return runOrError(cmd)
}

// Run runs the create, start, delete lifecycle of the container
// and returns its exit status after it has exited
func (r *Runc) Run(context context.Context, id, bundle string, opts *CreateOpts) (int, error) {
	args := []string{"run", "--bundle", bundle}
	if opts != nil {
		args = append(args, opts.args()...)
	}
	cmd := r.command(context, append(args, id)...)
	if opts != nil {
		opts.setSTDIO(cmd)
	}
	if err := cmd.Start(); err != nil {
		return -1, err
	}
	status, err := cmd.Process.Wait()
	if err != nil {
		return -1, err
	}
	return status.Sys().(syscall.WaitStatus).ExitStatus(), nil
}

// Delete deletes the container
func (r *Runc) Delete(context context.Context, id string) error {
	return runOrError(r.command(context, "delete", id))
}

// KillOpts specifies options for killing a container and its processes
type KillOpts struct {
	All bool
}

func (o *KillOpts) args() (out []string) {
	if o.All {
		out = append(out, "--all")
	}
	return out
}

// Kill sends the specified signal to the container
func (r *Runc) Kill(context context.Context, id string, sig int, opts *KillOpts) error {
	args := []string{
		"kill",
	}
	if opts != nil {
		args = append(args, opts.args()...)
	}
	return runOrError(r.command(context, append(args, id, strconv.Itoa(sig))...))
}

// Stats return the stats for a container like cpu, memory, and io
func (r *Runc) Stats(context context.Context, id string) (*Stats, error) {
	cmd := r.command(context, "events", "--stats", id)
	rd, err := cmd.StdoutPipe()
	if err != nil {
		return nil, err
	}
	defer func() {
		rd.Close()
		cmd.Wait()
	}()
	if err := cmd.Start(); err != nil {
		return nil, err
	}
	var e Event
	if err := json.NewDecoder(rd).Decode(&e); err != nil {
		return nil, err
	}
	return e.Stats, nil
}

// Events returns an event stream from runc for a container with stats and OOM notifications
func (r *Runc) Events(context context.Context, id string, interval time.Duration) (chan *Event, error) {
	cmd := r.command(context, "events", fmt.Sprintf("--interval=%ds", int(interval.Seconds())), id)
	rd, err := cmd.StdoutPipe()
	if err != nil {
		return nil, err
	}
	if err := cmd.Start(); err != nil {
		rd.Close()
		return nil, err
	}
	var (
		dec = json.NewDecoder(rd)
		c   = make(chan *Event, 128)
	)
	go func() {
		defer func() {
			close(c)
			rd.Close()
			cmd.Wait()
		}()
		for {
			var e Event
			if err := dec.Decode(&e); err != nil {
				if err == io.EOF {
					return
				}
				e = Event{
					Type: "error",
					Err:  err,
				}
			}
			c <- &e
		}
	}()
	return c, nil
}

// Pause the container with the provided id
func (r *Runc) Pause(context context.Context, id string) error {
	return runOrError(r.command(context, "pause", id))
}

// Resume the container with the provided id
func (r *Runc) Resume(context context.Context, id string) error {
	return runOrError(r.command(context, "resume", id))
}

// Ps lists all the processes inside the container returning their pids
func (r *Runc) Ps(context context.Context, id string) ([]int, error) {
	data, err := r.command(context, "ps", "--format", "json", id).CombinedOutput()
	if err != nil {
		return nil, fmt.Errorf("%s: %s", err, data)
	}
	var pids []int
	if err := json.Unmarshal(data, &pids); err != nil {
		return nil, err
	}
	return pids, nil
}

func (r *Runc) args() (out []string) {
	if r.Root != "" {
		out = append(out, "--root", r.Root)
	}
	if r.Debug {
		out = append(out, "--debug")
	}
	if r.Log != "" {
		out = append(out, "--log", r.Log)
	}
	if r.LogFormat != none {
		out = append(out, "--log-format", string(r.LogFormat))
	}
	return out
}

func (r *Runc) command(context context.Context, args ...string) *exec.Cmd {
	command := r.Command
	if command == "" {
		command = DefaultCommand
	}
	cmd := exec.CommandContext(context, command, append(r.args(), args...)...)
	if r.PdeathSignal != 0 {
		cmd.SysProcAttr = &syscall.SysProcAttr{
			Pdeathsig: r.PdeathSignal,
		}
	}
	return cmd
}
<|endoftext|>


<commit_before>package saml2

import (
	"encoding/base64"
	"sync"
	"time"

	"github.com/russellhaering/gosaml2/types"
	dsig "github.com/russellhaering/goxmldsig"
	dsigtypes "github.com/russellhaering/goxmldsig/types"
)

type ErrSaml struct {
	Message string
	System  error
}

func (serr ErrSaml) Error() string {
	if serr.Message != "" {
		return serr.Message
	}
	return "SAML error"
}

type SAMLServiceProvider struct {
	IdentityProviderSSOURL string
	IdentityProviderSSOBinding string
	IdentityProviderSLOURL string
	IdentityProviderSLOBinding string
	IdentityProviderIssuer string

	AssertionConsumerServiceURL string
	ServiceProviderSLOURL string
	ServiceProviderIssuer       string

	SignAuthnRequests              bool
	SignAuthnRequestsAlgorithm     string
	SignAuthnRequestsCanonicalizer dsig.Canonicalizer

	// RequestedAuthnContext allows service providers to require that the identity
	// provider use specific authentication mechanisms. Leaving this unset will
	// permit the identity provider to choose the auth method. To maximize compatibility
	// with identity providers it is recommended to leave this unset.
	RequestedAuthnContext   *RequestedAuthnContext
	AudienceURI             string
	IDPCertificateStore     dsig.X509CertificateStore
	SPKeyStore              dsig.X509KeyStore // Required encryption key, default signing key
	SPSigningKeyStore       dsig.X509KeyStore // Optional signing key
	NameIdFormat            string
	ValidateEncryptionCert  bool
	SkipSignatureValidation bool
	AllowMissingAttributes  bool
	Clock                   *dsig.Clock
	signingContextMu        sync.RWMutex
	signingContext          *dsig.SigningContext
}

// RequestedAuthnContext controls which authentication mechanisms are requested of
// the identity provider. It is generally sufficient to omit this and let the
// identity provider select an authentication mechansim.
type RequestedAuthnContext struct {
	// The RequestedAuthnContext comparison policy to use. See the section 3.3.2.2.1
	// of the SAML 2.0 specification for details. Constants named AuthnPolicyMatch*
	// contain standardized values.
	Comparison string

	// Contexts will be passed as AuthnContextClassRefs. For example, to force password
	// authentication on some identity providers, Contexts should have a value of
	// []string{AuthnContextPasswordProtectedTransport}, and Comparison should have a
	// value of AuthnPolicyMatchExact.
	Contexts []string
}

func (sp *SAMLServiceProvider) Metadata() (*types.EntityDescriptor, error) {
	signingCertBytes, err := sp.GetSigningCertBytes()
	if err != nil {
		return nil, err
	}
	encryptionCertBytes, err := sp.GetEncryptionCertBytes()
	if err != nil {
		return nil, err
	}
	return &types.EntityDescriptor{
		ValidUntil: time.Now().UTC().Add(time.Hour * 24 * 7), // 7 days
		EntityID:   sp.ServiceProviderIssuer,
		SPSSODescriptor: &types.SPSSODescriptor{
			AuthnRequestsSigned:        sp.SignAuthnRequests,
			WantAssertionsSigned:       !sp.SkipSignatureValidation,
			ProtocolSupportEnumeration: SAMLProtocolNamespace,
			KeyDescriptors: []types.KeyDescriptor{
				{
					Use: "signing",
					KeyInfo: dsigtypes.KeyInfo{
						X509Data: dsigtypes.X509Data{
							X509Certificates: []dsigtypes.X509Certificate{dsigtypes.X509Certificate{
								Data: base64.StdEncoding.EncodeToString(signingCertBytes),
							}},
						},
					},
				},
				{
					Use: "encryption",
					KeyInfo: dsigtypes.KeyInfo{
						X509Data: dsigtypes.X509Data{
							X509Certificates: []dsigtypes.X509Certificate{dsigtypes.X509Certificate{
								Data: base64.StdEncoding.EncodeToString(encryptionCertBytes),
							}},
						},
					},
					EncryptionMethods: []types.EncryptionMethod{
						{Algorithm: types.MethodAES128GCM, DigestMethod: types.DigestMethod{Algorithm: types.MethodSHA256}},
						{Algorithm: types.MethodAES128CBC, DigestMethod: types.DigestMethod{Algorithm: types.MethodSHA256}},
						{Algorithm: types.MethodAES256CBC, DigestMethod: types.DigestMethod{Algorithm: types.MethodSHA256}},
					},
				},
			},
			AssertionConsumerServices: []types.IndexedEndpoint{{
				Binding:  BindingHttpPost,
				Location: sp.AssertionConsumerServiceURL,
				Index:    1,
			}},
		},
	}, nil
}

func (sp *SAMLServiceProvider) MetadataWithSLO() (*types.EntityDescriptor, error) {
	signingCertBytes, err := sp.GetSigningCertBytes()
	if err != nil {
		return nil, err
	}
	encryptionCertBytes, err := sp.GetEncryptionCertBytes()
	if err != nil {
		return nil, err
	}
	return &types.EntityDescriptor{
		ValidUntil: time.Now().UTC().Add(time.Hour * 24 * 7), // 7 days
		EntityID:   sp.ServiceProviderIssuer,
		SPSSODescriptor: &types.SPSSODescriptor{
			AuthnRequestsSigned:        sp.SignAuthnRequests,
			WantAssertionsSigned:       !sp.SkipSignatureValidation,
			ProtocolSupportEnumeration: SAMLProtocolNamespace,
			KeyDescriptors: []types.KeyDescriptor{
				{
					Use: "signing",
					KeyInfo: dsigtypes.KeyInfo{
						X509Data: dsigtypes.X509Data{
							X509Certificates: []dsigtypes.X509Certificate{dsigtypes.X509Certificate{
								Data: base64.StdEncoding.EncodeToString(signingCertBytes),
							}},
						},
					},
				},
				{
					Use: "encryption",
					KeyInfo: dsigtypes.KeyInfo{
						X509Data: dsigtypes.X509Data{
							X509Certificates: []dsigtypes.X509Certificate{dsigtypes.X509Certificate{
								Data: base64.StdEncoding.EncodeToString(encryptionCertBytes),
							}},
						},
					},
					EncryptionMethods: []types.EncryptionMethod{
						{Algorithm: types.MethodAES128GCM, DigestMethod: types.DigestMethod{Algorithm: types.MethodSHA256}},
						{Algorithm: types.MethodAES128CBC, DigestMethod: types.DigestMethod{Algorithm: types.MethodSHA256}},
						{Algorithm: types.MethodAES256CBC, DigestMethod: types.DigestMethod{Algorithm: types.MethodSHA256}},
					},
				},
			},
			AssertionConsumerServices: []types.IndexedEndpoint{{
				Binding:  BindingHttpPost,
				Location: sp.AssertionConsumerServiceURL,
				Index:    1,
			}},
			SingleLogoutServices: []types.Endpoint{{
				Binding:  BindingHttpRedirect,
				Location: sp.ServiceProviderSLOURL,
			}, {
				Binding:  BindingHttpPost,
				Location: sp.ServiceProviderSLOURL,
            }},
		},
	}, nil
}

func (sp *SAMLServiceProvider) GetEncryptionKey() dsig.X509KeyStore {
	return sp.SPKeyStore
}

func (sp *SAMLServiceProvider) GetSigningKey() dsig.X509KeyStore {
	if sp.SPSigningKeyStore == nil {
		return sp.GetEncryptionKey() // Default is signing key is same as encryption key
	}
	return sp.SPSigningKeyStore
}

func (sp *SAMLServiceProvider) GetEncryptionCertBytes() ([]byte, error) {
	if _, encryptionCert, err := sp.GetEncryptionKey().GetKeyPair(); err != nil {
		return nil, ErrSaml{Message: "no SP encryption certificate", System: err}
	} else if len(encryptionCert) < 1 {
		return nil, ErrSaml{Message: "empty SP encryption certificate"}
	} else {
		return encryptionCert, nil
	}
}

func (sp *SAMLServiceProvider) GetSigningCertBytes() ([]byte, error) {
	if _, signingCert, err := sp.GetSigningKey().GetKeyPair(); err != nil {
		return nil, ErrSaml{Message: "no SP signing certificate", System: err}
	} else if len(signingCert) < 1 {
		return nil, ErrSaml{Message: "empty SP signing certificate"}
	} else {
		return signingCert, nil
	}
}

func (sp *SAMLServiceProvider) SigningContext() *dsig.SigningContext {
	sp.signingContextMu.RLock()
	signingContext := sp.signingContext
	sp.signingContextMu.RUnlock()

	if signingContext != nil {
		return signingContext
	}

	sp.signingContextMu.Lock()
	defer sp.signingContextMu.Unlock()

	sp.signingContext = dsig.NewDefaultSigningContext(sp.GetSigningKey())
	sp.signingContext.SetSignatureMethod(sp.SignAuthnRequestsAlgorithm)
	if sp.SignAuthnRequestsCanonicalizer != nil {
		sp.signingContext.Canonicalizer = sp.SignAuthnRequestsCanonicalizer
	}

	return sp.signingContext
}

type ProxyRestriction struct {
	Count    int
	Audience []string
}

type WarningInfo struct {
	OneTimeUse       bool
	ProxyRestriction *ProxyRestriction
	NotInAudience    bool
	InvalidTime      bool
}

type AssertionInfo struct {
	NameID                     string
	Values                     Values
	WarningInfo                *WarningInfo
	AuthnInstant               *time.Time
	SessionNotOnOrAfter        *time.Time
	Assertions                 []types.Assertion
	ResponseSignatureValidated bool
}
<commit_msg>SP metadata with SLO - remove Redirect binding<commit_after>package saml2

import (
	"encoding/base64"
	"sync"
	"time"

	"github.com/russellhaering/gosaml2/types"
	dsig "github.com/russellhaering/goxmldsig"
	dsigtypes "github.com/russellhaering/goxmldsig/types"
)

type ErrSaml struct {
	Message string
	System  error
}

func (serr ErrSaml) Error() string {
	if serr.Message != "" {
		return serr.Message
	}
	return "SAML error"
}

type SAMLServiceProvider struct {
	IdentityProviderSSOURL string
	IdentityProviderSSOBinding string
	IdentityProviderSLOURL string
	IdentityProviderSLOBinding string
	IdentityProviderIssuer string

	AssertionConsumerServiceURL string
	ServiceProviderSLOURL string
	ServiceProviderIssuer       string

	SignAuthnRequests              bool
	SignAuthnRequestsAlgorithm     string
	SignAuthnRequestsCanonicalizer dsig.Canonicalizer

	// RequestedAuthnContext allows service providers to require that the identity
	// provider use specific authentication mechanisms. Leaving this unset will
	// permit the identity provider to choose the auth method. To maximize compatibility
	// with identity providers it is recommended to leave this unset.
	RequestedAuthnContext   *RequestedAuthnContext
	AudienceURI             string
	IDPCertificateStore     dsig.X509CertificateStore
	SPKeyStore              dsig.X509KeyStore // Required encryption key, default signing key
	SPSigningKeyStore       dsig.X509KeyStore // Optional signing key
	NameIdFormat            string
	ValidateEncryptionCert  bool
	SkipSignatureValidation bool
	AllowMissingAttributes  bool
	Clock                   *dsig.Clock
	signingContextMu        sync.RWMutex
	signingContext          *dsig.SigningContext
}

// RequestedAuthnContext controls which authentication mechanisms are requested of
// the identity provider. It is generally sufficient to omit this and let the
// identity provider select an authentication mechansim.
type RequestedAuthnContext struct {
	// The RequestedAuthnContext comparison policy to use. See the section 3.3.2.2.1
	// of the SAML 2.0 specification for details. Constants named AuthnPolicyMatch*
	// contain standardized values.
	Comparison string

	// Contexts will be passed as AuthnContextClassRefs. For example, to force password
	// authentication on some identity providers, Contexts should have a value of
	// []string{AuthnContextPasswordProtectedTransport}, and Comparison should have a
	// value of AuthnPolicyMatchExact.
	Contexts []string
}

func (sp *SAMLServiceProvider) Metadata() (*types.EntityDescriptor, error) {
	signingCertBytes, err := sp.GetSigningCertBytes()
	if err != nil {
		return nil, err
	}
	encryptionCertBytes, err := sp.GetEncryptionCertBytes()
	if err != nil {
		return nil, err
	}
	return &types.EntityDescriptor{
		ValidUntil: time.Now().UTC().Add(time.Hour * 24 * 7), // 7 days
		EntityID:   sp.ServiceProviderIssuer,
		SPSSODescriptor: &types.SPSSODescriptor{
			AuthnRequestsSigned:        sp.SignAuthnRequests,
			WantAssertionsSigned:       !sp.SkipSignatureValidation,
			ProtocolSupportEnumeration: SAMLProtocolNamespace,
			KeyDescriptors: []types.KeyDescriptor{
				{
					Use: "signing",
					KeyInfo: dsigtypes.KeyInfo{
						X509Data: dsigtypes.X509Data{
							X509Certificates: []dsigtypes.X509Certificate{dsigtypes.X509Certificate{
								Data: base64.StdEncoding.EncodeToString(signingCertBytes),
							}},
						},
					},
				},
				{
					Use: "encryption",
					KeyInfo: dsigtypes.KeyInfo{
						X509Data: dsigtypes.X509Data{
							X509Certificates: []dsigtypes.X509Certificate{dsigtypes.X509Certificate{
								Data: base64.StdEncoding.EncodeToString(encryptionCertBytes),
							}},
						},
					},
					EncryptionMethods: []types.EncryptionMethod{
						{Algorithm: types.MethodAES128GCM, DigestMethod: types.DigestMethod{Algorithm: types.MethodSHA256}},
						{Algorithm: types.MethodAES128CBC, DigestMethod: types.DigestMethod{Algorithm: types.MethodSHA256}},
						{Algorithm: types.MethodAES256CBC, DigestMethod: types.DigestMethod{Algorithm: types.MethodSHA256}},
					},
				},
			},
			AssertionConsumerServices: []types.IndexedEndpoint{{
				Binding:  BindingHttpPost,
				Location: sp.AssertionConsumerServiceURL,
				Index:    1,
			}},
		},
	}, nil
}

func (sp *SAMLServiceProvider) MetadataWithSLO() (*types.EntityDescriptor, error) {
	signingCertBytes, err := sp.GetSigningCertBytes()
	if err != nil {
		return nil, err
	}
	encryptionCertBytes, err := sp.GetEncryptionCertBytes()
	if err != nil {
		return nil, err
	}
	return &types.EntityDescriptor{
		ValidUntil: time.Now().UTC().Add(time.Hour * 24 * 7), // 7 days
		EntityID:   sp.ServiceProviderIssuer,
		SPSSODescriptor: &types.SPSSODescriptor{
			AuthnRequestsSigned:        sp.SignAuthnRequests,
			WantAssertionsSigned:       !sp.SkipSignatureValidation,
			ProtocolSupportEnumeration: SAMLProtocolNamespace,
			KeyDescriptors: []types.KeyDescriptor{
				{
					Use: "signing",
					KeyInfo: dsigtypes.KeyInfo{
						X509Data: dsigtypes.X509Data{
							X509Certificates: []dsigtypes.X509Certificate{dsigtypes.X509Certificate{
								Data: base64.StdEncoding.EncodeToString(signingCertBytes),
							}},
						},
					},
				},
				{
					Use: "encryption",
					KeyInfo: dsigtypes.KeyInfo{
						X509Data: dsigtypes.X509Data{
							X509Certificates: []dsigtypes.X509Certificate{dsigtypes.X509Certificate{
								Data: base64.StdEncoding.EncodeToString(encryptionCertBytes),
							}},
						},
					},
					EncryptionMethods: []types.EncryptionMethod{
						{Algorithm: types.MethodAES128GCM, DigestMethod: types.DigestMethod{Algorithm: types.MethodSHA256}},
						{Algorithm: types.MethodAES128CBC, DigestMethod: types.DigestMethod{Algorithm: types.MethodSHA256}},
						{Algorithm: types.MethodAES256CBC, DigestMethod: types.DigestMethod{Algorithm: types.MethodSHA256}},
					},
				},
			},
			AssertionConsumerServices: []types.IndexedEndpoint{{
				Binding:  BindingHttpPost,
				Location: sp.AssertionConsumerServiceURL,
				Index:    1,
			}},
			SingleLogoutServices: []types.Endpoint{{
				Binding:  BindingHttpPost,
				Location: sp.ServiceProviderSLOURL,
            }},
		},
	}, nil
}

func (sp *SAMLServiceProvider) GetEncryptionKey() dsig.X509KeyStore {
	return sp.SPKeyStore
}

func (sp *SAMLServiceProvider) GetSigningKey() dsig.X509KeyStore {
	if sp.SPSigningKeyStore == nil {
		return sp.GetEncryptionKey() // Default is signing key is same as encryption key
	}
	return sp.SPSigningKeyStore
}

func (sp *SAMLServiceProvider) GetEncryptionCertBytes() ([]byte, error) {
	if _, encryptionCert, err := sp.GetEncryptionKey().GetKeyPair(); err != nil {
		return nil, ErrSaml{Message: "no SP encryption certificate", System: err}
	} else if len(encryptionCert) < 1 {
		return nil, ErrSaml{Message: "empty SP encryption certificate"}
	} else {
		return encryptionCert, nil
	}
}

func (sp *SAMLServiceProvider) GetSigningCertBytes() ([]byte, error) {
	if _, signingCert, err := sp.GetSigningKey().GetKeyPair(); err != nil {
		return nil, ErrSaml{Message: "no SP signing certificate", System: err}
	} else if len(signingCert) < 1 {
		return nil, ErrSaml{Message: "empty SP signing certificate"}
	} else {
		return signingCert, nil
	}
}

func (sp *SAMLServiceProvider) SigningContext() *dsig.SigningContext {
	sp.signingContextMu.RLock()
	signingContext := sp.signingContext
	sp.signingContextMu.RUnlock()

	if signingContext != nil {
		return signingContext
	}

	sp.signingContextMu.Lock()
	defer sp.signingContextMu.Unlock()

	sp.signingContext = dsig.NewDefaultSigningContext(sp.GetSigningKey())
	sp.signingContext.SetSignatureMethod(sp.SignAuthnRequestsAlgorithm)
	if sp.SignAuthnRequestsCanonicalizer != nil {
		sp.signingContext.Canonicalizer = sp.SignAuthnRequestsCanonicalizer
	}

	return sp.signingContext
}

type ProxyRestriction struct {
	Count    int
	Audience []string
}

type WarningInfo struct {
	OneTimeUse       bool
	ProxyRestriction *ProxyRestriction
	NotInAudience    bool
	InvalidTime      bool
}

type AssertionInfo struct {
	NameID                     string
	Values                     Values
	WarningInfo                *WarningInfo
	AuthnInstant               *time.Time
	SessionNotOnOrAfter        *time.Time
	Assertions                 []types.Assertion
	ResponseSignatureValidated bool
}
<|endoftext|>


<commit_before>package scipipe

import (
	"time"
)

// Sink is a simple component that just receives InformationPacket on its In-port
// without doing anything with them
type Sink struct {
	Process
	name    string
	inPorts []*FilePort
}

// Instantiate a Sink component
func NewSink(name string) (s *Sink) {
	return &Sink{
		name:    name,
		inPorts: []*FilePort{},
	}
}

func (p *Sink) IsConnected() bool {
	if len(p.inPorts) > 0 {
		return true
	} else {
		return false
	}
}

func (p *Sink) Connect(outPort *FilePort) {
	newInPort := NewFilePort()
	newInPort.Connect(outPort)
	p.inPorts = append(p.inPorts, newInPort)
}

func (p *Sink) Name() string {
	return p.name
}

// Execute the Sink component
func (p *Sink) Run() {
	ok := true
	var ft *InformationPacket
	for len(p.inPorts) > 0 {
	loop:
		for i, inp := range p.inPorts {
			select {
			case ft, ok = <-inp.Chan:
				if !ok {
					Debug.Println(p.name + ": Channel closed, so deleting, and restarting loop")
					p.deleteInPortAtKey(i)
					break loop
				}
				Debug.Println(p.name+": Received file in sink: ", ft.GetPath())
			default:
				Debug.Printf(p.name+": No receive on inport %d, so continuing ...\n", i)
				time.Sleep(100 * time.Millisecond)
			}
		}
	}
}
<commit_msg>simplify function: remove if<commit_after>package scipipe

import (
	"time"
)

// Sink is a simple component that just receives InformationPacket on its In-port
// without doing anything with them
type Sink struct {
	Process
	name    string
	inPorts []*FilePort
}

// Instantiate a Sink component
func NewSink(name string) (s *Sink) {
	return &Sink{
		name:    name,
		inPorts: []*FilePort{},
	}
}

func (p *Sink) IsConnected() bool {
	return len(p.inPorts) > 0
}

func (p *Sink) Connect(outPort *FilePort) {
	newInPort := NewFilePort()
	newInPort.Connect(outPort)
	p.inPorts = append(p.inPorts, newInPort)
}

func (p *Sink) Name() string {
	return p.name
}

// Execute the Sink component
func (p *Sink) Run() {
	ok := true
	var ft *InformationPacket
	for len(p.inPorts) > 0 {
	loop:
		for i, inp := range p.inPorts {
			select {
			case ft, ok = <-inp.Chan:
				if !ok {
					Debug.Println(p.name + ": Channel closed, so deleting, and restarting loop")
					p.deleteInPortAtKey(i)
					break loop
				}
				Debug.Println(p.name+": Received file in sink: ", ft.GetPath())
			default:
				Debug.Printf(p.name+": No receive on inport %d, so continuing ...\n", i)
				time.Sleep(100 * time.Millisecond)
			}
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
  "fmt"
  "bufio"
  "runtime"
  "os"
)

func main() {
  runtime.GOMAXPROCS(runtime.NumCPU())

  scanner := bufio.NewScanner(os.Stdin)

  freq := make(map[rune]int)
  total := 0

  for scanner.Scan() {
    someline := scanner.Text()

    for i, r := range someline {
      freq[r] += 1
      total += 1

      fmt.Println(i, len(someline))
    }
  }

  lexd := 1.0*float64(len(freq))/float64(total)
  avg := 1.0*float64(total)/float64(len(freq))

  fmt.Println(len(freq), freq, total, "lexd", lexd, "avg", avg)
}
<commit_msg>muhaha<commit_after>package main

import (
  "fmt"
  "bufio"
  "runtime"
  "os"
)

type bigram struct {
  left rune
  right rune
}

func (b bigram) String() string {
  return string(b.left) + string(b.right)
}

/*
(
len(X.union(Y))
-
len(X.intersection(Y))
)
/
float(len(X.union(Y)))
*/

func jaccard(x, y []bigram) {
  intersection := make(map[bigram]int)
  union := make(map[bigram]int)

  for _, xrune := range x {
    for _, yrune := range y {
      if (xrune.left == yrune.left) && (xrune.right == yrune.right) {
        intersection[xrune] += 1
        union[xrune] += 1
      } else {
        union[xrune] += 1
        union[yrune] += 1
      }
    }
  }

  distance := 1 - ((float64(len(union)) - float64(len(intersection))) / float64(len(union)))

  if distance > 0.5 && distance < 1.0 {
    fmt.Println(distance)
    fmt.Println(x)
    fmt.Println(y)
  }
}

func main() {
  runtime.GOMAXPROCS(runtime.NumCPU())

  scanner := bufio.NewScanner(os.Stdin)

  bigramsarray := make([][]bigram, 0)

  freq := make(map[rune]int)
  total := 0

  for scanner.Scan() {
    bigrams := make([]bigram, 0)

    someline := scanner.Text()

    var prev rune
    var endrune rune

    for _, r := range someline {
      freq[r] += 1
      total += 1
      bigrams = append(bigrams, bigram{prev, r})
      prev = r
    }

    bigrams = append(bigrams, bigram{prev, endrune})

    bigramsarray = append(bigramsarray, bigrams)
  }

  lexd := 1.0*float64(len(freq))/float64(total)
  avg := 1.0*float64(total)/float64(len(freq))

  fmt.Println(len(freq), freq, total, "lexd", lexd, "avg", avg)

  for _, x := range bigramsarray {
    for _, y := range bigramsarray {
      jaccard(x, y)
    }
  }
}
<|endoftext|>


<commit_before>// smaz is an implementation of the smaz library (https://github.com/antirez/smaz) for compressing small
// strings.
package smaz

import (
	"bytes"
	"errors"
)

var codes = []string{" ",
	"the", "e", "t", "a", "of", "o", "and", "i", "n", "s", "e ", "r", " th",
	" t", "in", "he", "th", "h", "he ", "to", "\r\n", "l", "s ", "d", " a", "an",
	"er", "c", " o", "d ", "on", " of", "re", "of ", "t ", ", ", "is", "u", "at",
	"   ", "n ", "or", "which", "f", "m", "as", "it", "that", "\n", "was", "en",
	"  ", " w", "es", " an", " i", "\r", "f ", "g", "p", "nd", " s", "nd ", "ed ",
	"w", "ed", "http://", "for", "te", "ing", "y ", "The", " c", "ti", "r ", "his",
	"st", " in", "ar", "nt", ",", " to", "y", "ng", " h", "with", "le", "al", "to ",
	"b", "ou", "be", "were", " b", "se", "o ", "ent", "ha", "ng ", "their", "\"",
	"hi", "from", " f", "in ", "de", "ion", "me", "v", ".", "ve", "all", "re ",
	"ri", "ro", "is ", "co", "f t", "are", "ea", ". ", "her", " m", "er ", " p",
	"es ", "by", "they", "di", "ra", "ic", "not", "s, ", "d t", "at ", "ce", "la",
	"h ", "ne", "as ", "tio", "on ", "n t", "io", "we", " a ", "om", ", a", "s o",
	"ur", "li", "ll", "ch", "had", "this", "e t", "g ", "e\r\n", " wh", "ere",
	" co", "e o", "a ", "us", " d", "ss", "\n\r\n", "\r\n\r", "=\"", " be", " e",
	"s a", "ma", "one", "t t", "or ", "but", "el", "so", "l ", "e s", "s,", "no",
	"ter", " wa", "iv", "ho", "e a", " r", "hat", "s t", "ns", "ch ", "wh", "tr",
	"ut", "/", "have", "ly ", "ta", " ha", " on", "tha", "-", " l", "ati", "en ",
	"pe", " re", "there", "ass", "si", " fo", "wa", "ec", "our", "who", "its", "z",
	"fo", "rs", ">", "ot", "un", "<", "im", "th ", "nc", "ate", "><", "ver", "ad",
	" we", "ly", "ee", " n", "id", " cl", "ac", "il", "</", "rt", " wi", "div",
	"e, ", " it", "whi", " ma", "ge", "x", "e c", "men", ".com",
}

var codeArrays = make([][]byte, len(codes))
var prefixToCode = make(map[string]byte)
var maxCodeLength = 0 // TODO: Unnecessary when we switch to a trie implementation

// Library initialization.
func init() {
	for i, code := range codes {
		codeArrays[i] = []byte(code)
		prefixToCode[code] = byte(i)
		if len(code) > maxCodeLength {
			maxCodeLength = len(code)
		}
	}
}

// Compress a byte array and return a new byte array with the compressed data.
// TODO: This function is written in an extremely naive manner for the time being and is very slow. I will
// reimplement (and then profile/optimize it) after I get done with go-trie, which will be a natural fit for
// this problem.
func Compress(input []byte) (compressed []byte) {
	var outputBuffer bytes.Buffer
	var verbatim bytes.Buffer
	remaining := len(input)
	position := 0

	flushVerbatim := func() {
		// We can write a max of 255 continuous verbatim characters, because the length of the continous verbatim
		// section is represented by a single byte.
		for verbatim.Len() > 0 {
			chunk := verbatim.Next(255)
			if len(chunk) == 1 {
				// 254 is code for a single verbatim byte
				outputBuffer.WriteByte(byte(254))
			} else {
				// 255 is code for a verbatim string. It is followed by a byte containing the length of the string.
				outputBuffer.WriteByte(byte(255))
				outputBuffer.WriteByte(byte(len(chunk)))
			}
			outputBuffer.Write(chunk)
		}
		verbatim.Reset()
	}

	for remaining > 0 {
		// Find the longest matching substring, brute-force
		longestPossibleMatch := maxCodeLength
		if remaining < longestPossibleMatch {
			longestPossibleMatch = remaining
		}
		matchFound := false
		for i := longestPossibleMatch; i > 0; i-- {
			prefix := input[position : position+i]
			/*fmt.Printf("Prefix: %v\n", string(prefix))*/
			if code, ok := prefixToCode[string(prefix)]; ok {
				// Match found
				remaining -= i
				position += i
				flushVerbatim()
				outputBuffer.WriteByte(code)
				matchFound = true
				break
			}
		}
		if !matchFound {
			verbatim.WriteByte(input[position])
			remaining -= 1
			position += 1
		}
	}
	flushVerbatim()

	return outputBuffer.Bytes()
}

var DecompressionError = errors.New("Invalid or corrupt compressed data.")

// Decompress a byte array and return a new array with the decompressed data. If the decompression fails for
// some reason, err will be non-nil.
func Decompress(compressed []byte) (output []byte, err error) {
	var decompressed bytes.Buffer
	var remaining = len(compressed)
	var position = 0
	var dummy []byte

	for remaining > 0 {
		switch compressed[position] {
		case 254:
			// Verbatim byte
			if remaining < 2 {
				return dummy, err
			}
			decompressed.WriteByte(compressed[position+1])
			remaining -= 2
			position += 2
		case 255:
			// Verbatim string
			if remaining < 2 {
				return dummy, err
			}
			length := int(compressed[position+1])
			if remaining < length+2 {
				return dummy, err
			}
			decompressed.Write(compressed[position+2 : position+length+2])
			remaining -= length + 2
			position += length + 2
		default:
			// Look up encoded value
			decompressed.Write([]byte(codes[int(compressed[position])]))
			remaining--
			position++
		}
	}

	return decompressed.Bytes(), nil
}
<commit_msg>General cleanup pass and bugfix.<commit_after>// Package smaz is an implementation of the smaz library (https://github.com/antirez/smaz) for compressing
// small strings.
package smaz

import (
	"bytes"
	"errors"
)

var codes = []string{" ",
	"the", "e", "t", "a", "of", "o", "and", "i", "n", "s", "e ", "r", " th",
	" t", "in", "he", "th", "h", "he ", "to", "\r\n", "l", "s ", "d", " a", "an",
	"er", "c", " o", "d ", "on", " of", "re", "of ", "t ", ", ", "is", "u", "at",
	"   ", "n ", "or", "which", "f", "m", "as", "it", "that", "\n", "was", "en",
	"  ", " w", "es", " an", " i", "\r", "f ", "g", "p", "nd", " s", "nd ", "ed ",
	"w", "ed", "http://", "for", "te", "ing", "y ", "The", " c", "ti", "r ", "his",
	"st", " in", "ar", "nt", ",", " to", "y", "ng", " h", "with", "le", "al", "to ",
	"b", "ou", "be", "were", " b", "se", "o ", "ent", "ha", "ng ", "their", "\"",
	"hi", "from", " f", "in ", "de", "ion", "me", "v", ".", "ve", "all", "re ",
	"ri", "ro", "is ", "co", "f t", "are", "ea", ". ", "her", " m", "er ", " p",
	"es ", "by", "they", "di", "ra", "ic", "not", "s, ", "d t", "at ", "ce", "la",
	"h ", "ne", "as ", "tio", "on ", "n t", "io", "we", " a ", "om", ", a", "s o",
	"ur", "li", "ll", "ch", "had", "this", "e t", "g ", "e\r\n", " wh", "ere",
	" co", "e o", "a ", "us", " d", "ss", "\n\r\n", "\r\n\r", "=\"", " be", " e",
	"s a", "ma", "one", "t t", "or ", "but", "el", "so", "l ", "e s", "s,", "no",
	"ter", " wa", "iv", "ho", "e a", " r", "hat", "s t", "ns", "ch ", "wh", "tr",
	"ut", "/", "have", "ly ", "ta", " ha", " on", "tha", "-", " l", "ati", "en ",
	"pe", " re", "there", "ass", "si", " fo", "wa", "ec", "our", "who", "its", "z",
	"fo", "rs", ">", "ot", "un", "<", "im", "th ", "nc", "ate", "><", "ver", "ad",
	" we", "ly", "ee", " n", "id", " cl", "ac", "il", "</", "rt", " wi", "div",
	"e, ", " it", "whi", " ma", "ge", "x", "e c", "men", ".com",
}

var codeArrays = make([][]byte, len(codes))
var prefixToCode = make(map[string]byte)
var maxCodeLength = 0 // TODO: Unnecessary when we switch to a trie implementation

// Library initialization.
func init() {
	for i, code := range codes {
		codeArrays[i] = []byte(code)
		prefixToCode[code] = byte(i)
		if len(code) > maxCodeLength {
			maxCodeLength = len(code)
		}
	}
}

// BUG(cespare): Compress is written in an extremely naive manner for the time being and is very slow. I will
// reimplement (and then profile/optimize it) after I get done with go-trie, which will be a natural fit for
// this problem.

// Compress compresses a byte slice and returns the compressed data.
func Compress(input []byte) []byte {
	var outputBuffer bytes.Buffer
	var verbatim bytes.Buffer
	remaining := len(input)
	position := 0

	flushVerbatim := func() {
		// We can write a max of 255 continuous verbatim characters, because the length of the continous verbatim
		// section is represented by a single byte.
		for verbatim.Len() > 0 {
			chunk := verbatim.Next(255)
			if len(chunk) == 1 {
				// 254 is code for a single verbatim byte
				outputBuffer.WriteByte(byte(254))
			} else {
				// 255 is code for a verbatim string. It is followed by a byte containing the length of the string.
				outputBuffer.WriteByte(byte(255))
				outputBuffer.WriteByte(byte(len(chunk)))
			}
			outputBuffer.Write(chunk)
		}
		verbatim.Reset()
	}

	for remaining > 0 {
		// Find the longest matching substring, brute-force
		longestPossibleMatch := maxCodeLength
		if remaining < longestPossibleMatch {
			longestPossibleMatch = remaining
		}
		matchFound := false
		for i := longestPossibleMatch; i > 0; i-- {
			prefix := input[position : position+i]
			/*fmt.Printf("Prefix: %v\n", string(prefix))*/
			if code, ok := prefixToCode[string(prefix)]; ok {
				// Match found
				remaining -= i
				position += i
				flushVerbatim()
				outputBuffer.WriteByte(code)
				matchFound = true
				break
			}
		}
		if !matchFound {
			verbatim.WriteByte(input[position])
			remaining -= 1
			position += 1
		}
	}
	flushVerbatim()

	return outputBuffer.Bytes()
}

var decompressionError = errors.New("Invalid or corrupted compressed data.")

// Decompress decompresses a smaz-compressed byte slice and return a new slice with the decompressed data. err
// is nil if and only if decompression fails for any reason (e.g., corrupted data).
func Decompress(compressed []byte) ([]byte, error) {
	var decompressed bytes.Buffer
	var remaining = len(compressed)
	var position = 0

	for remaining > 0 {
		switch compressed[position] {
		case 254:
			// Verbatim byte
			if remaining < 2 {
				return nil, decompressionError
			}
			decompressed.WriteByte(compressed[position+1])
			remaining -= 2
			position += 2
		case 255:
			// Verbatim string
			if remaining < 2 {
				return nil, decompressionError
			}
			length := int(compressed[position+1])
			if remaining < length+2 {
				return nil, decompressionError
			}
			decompressed.Write(compressed[position+2 : position+length+2])
			remaining -= length + 2
			position += length + 2
		default:
			// Look up encoded value
			decompressed.Write([]byte(codes[int(compressed[position])]))
			remaining--
			position++
		}
	}

	return decompressed.Bytes(), nil
}
<|endoftext|>


<commit_before>// Copyright 2014 Igor Dolzhikov. All rights reserved.
// Use of this source code is governed by a license
// that can be found in the LICENSE file.

/*
Package tags 0.1.3

Definition:

	- Tags - a strings which used for tag any object
	- Non-strict Tags - a strings which match to strings in data ("new" -> "new")
	- Strict Tags - all strict tags have prefix "+" for strict match ("+new")
	    and "-" for strict mismatch ("-old")

Rules:

	- All strict Tags applied with logical operator "AND" between each other
	- All non-strict Tags applied with logical operator "OR" between all tags

Queries:

	{"a","b"} this mean that we ask "a" OR "b" tag
	{"a","+b","+c"} this mean that we ask "a" OR ("b" AND "c") tag
	{"a","+b", "c", "-d"} this mean that we ask "a" OR "c" OR ("b" AND NOT "d") tag

Example:

	package main

	import (
		"fmt"

		"github.com/takama/tags"
	)

	// Product is struct with tags
	type Product struct {
		Name        string
		Description string
		Tags        tags.Tags
	}

	func main() {
		product := Product{
			Name:        "the tee",
			Description: "the boutle of ice black tee with sugar",
			Tags:        tags.Tags{"ice", "black", "sugar"},
		}

		fmt.Println("Product:", product.Description)

		// We ask for any tee "black" or "green"
		fmt.Println("Is this tee black or green?")
		query := tags.Tags{"black", "green"}

		if product.Tags.IsTagged(query) {
			fmt.Println("Yes, the tee is black.")
		} else {
			fmt.Println("No, the tee has not black or green options.")
		}

		// We ask fot strict match "green" and "sugar"
		fmt.Println("Is this tee green with sugar?")
		query = tags.Tags{"+green", "+sugar"}

		if product.Tags.IsTagged(query) {
			fmt.Println("Yes, the tee is green with sugar.")
		} else {
			fmt.Println("No, the tee with sugar, but is not green.")
		}

		// We ask for strict mismatch, not "ice"
		fmt.Println("Is this tee hot?")
		query = tags.Tags{"-ice"}

		if product.Tags.IsTagged(query) {
			fmt.Println("Yes, the tee is hot.")
		} else {
			fmt.Println("No, it is ice tee.")
		}
	}

Go Tags
*/
package tags

import (
	"strings"
)

// Tags is a slice of strings which used for tag any object
type Tags []string

// IsTagged - this method checks if Tags are matched with tags in query
func (t Tags) IsTagged(query Tags) bool {
	if len(query) == 0 {
		return true
	}
	if len(t) == 0 {
		return false
	}
	for _, qTag := range query {
		for _, tag := range t {
			if tag == qTag {
				return true
			}
		}
	}

	var strict uint8
	for _, qTag := range query {
		if strings.HasPrefix(qTag, "+") || strings.HasPrefix(qTag, "-") {
			strict++
		}
	}
	if strict == 0 {
		return false
	}
	for _, qTag := range query {
		if strings.HasPrefix(qTag, "+") {
			for _, tag := range t {
				if tag == strings.TrimPrefix(qTag, "+") {
					strict--
					break
				}
			}
		}
		if strings.HasPrefix(qTag, "-") {
			fit := true
			for _, tag := range t {
				if tag == strings.TrimPrefix(qTag, "-") {
					fit = false
					break
				}
			}
			if fit {
				strict--
			}
		}
	}

	return strict == 0
}
<commit_msg>Bumped version number to 0.1.4<commit_after>// Copyright 2014 Igor Dolzhikov. All rights reserved.
// Use of this source code is governed by a license
// that can be found in the LICENSE file.

/*
Package tags 0.1.4

Definition:

	- Tags - a strings which used for tag any object
	- Non-strict Tags - a strings which match to strings in data ("new" -> "new")
	- Strict Tags - all strict tags have prefix "+" for strict match ("+new")
	    and "-" for strict mismatch ("-old")

Rules:

	- All strict Tags applied with logical operator "AND" between each other
	- All non-strict Tags applied with logical operator "OR" between all tags

Queries:

	{"a","b"} this mean that we ask "a" OR "b" tag
	{"a","+b","+c"} this mean that we ask "a" OR ("b" AND "c") tag
	{"a","+b", "c", "-d"} this mean that we ask "a" OR "c" OR ("b" AND NOT "d") tag

Example:

	package main

	import (
		"fmt"

		"github.com/takama/tags"
	)

	// Product is struct with tags
	type Product struct {
		Name        string
		Description string
		Tags        tags.Tags
	}

	func main() {
		product := Product{
			Name:        "the tee",
			Description: "the boutle of ice black tee with sugar",
			Tags:        tags.Tags{"ice", "black", "sugar"},
		}

		fmt.Println("Product:", product.Description)

		// We ask for any tee "black" or "green"
		fmt.Println("Is this tee black or green?")
		query := tags.Tags{"black", "green"}

		if product.Tags.IsTagged(query) {
			fmt.Println("Yes, the tee is black.")
		} else {
			fmt.Println("No, the tee has not black or green options.")
		}

		// We ask fot strict match "green" and "sugar"
		fmt.Println("Is this tee green with sugar?")
		query = tags.Tags{"+green", "+sugar"}

		if product.Tags.IsTagged(query) {
			fmt.Println("Yes, the tee is green with sugar.")
		} else {
			fmt.Println("No, the tee with sugar, but is not green.")
		}

		// We ask for strict mismatch, not "ice"
		fmt.Println("Is this tee hot?")
		query = tags.Tags{"-ice"}

		if product.Tags.IsTagged(query) {
			fmt.Println("Yes, the tee is hot.")
		} else {
			fmt.Println("No, it is ice tee.")
		}
	}

Go Tags
*/
package tags

import (
	"strings"
)

// Tags is a slice of strings which used for tag any object
type Tags []string

// IsTagged - this method checks if Tags are matched with tags in query
func (t Tags) IsTagged(query Tags) bool {
	if len(query) == 0 {
		return true
	}
	if len(t) == 0 {
		return false
	}
	for _, qTag := range query {
		for _, tag := range t {
			if tag == qTag {
				return true
			}
		}
	}

	var strict uint8
	for _, qTag := range query {
		if strings.HasPrefix(qTag, "+") || strings.HasPrefix(qTag, "-") {
			strict++
		}
	}
	if strict == 0 {
		return false
	}
	for _, qTag := range query {
		if strings.HasPrefix(qTag, "+") {
			for _, tag := range t {
				if tag == strings.TrimPrefix(qTag, "+") {
					strict--
					break
				}
			}
		}
		if strings.HasPrefix(qTag, "-") {
			fit := true
			for _, tag := range t {
				if tag == strings.TrimPrefix(qTag, "-") {
					fit = false
					break
				}
			}
			if fit {
				strict--
			}
		}
	}

	return strict == 0
}
<|endoftext|>


<commit_before>// Copyright (C) 2015 Thomas de Zeeuw.
//
// Licensed under the MIT license that can be found in the LICENSE file.

package logger

import "strconv"

// Tags are keywords usefull in searching through logs, for example:
//
//	tags := Tags{"file.go", "myFn", "user:$user_id", "input:$input"}
//
// With this information you can lookup any logs for a specific user reporting
// an issue. Then you can find which function, in which file, is throwing the
// error.
type Tags []string

// String creates a comma separated list from the tags in string.
func (tags Tags) String() string {
	return string(tags.Bytes())
}

// Bytes does the same as Tags.String, but returns a byte slice.
func (tags Tags) Bytes() []byte {
	if len(tags) == 0 {
		return []byte{}
	}

	// Add each tag in the form of "tag, ".
	var buf []byte
	for _, tag := range tags {
		buf = append(buf, tag...)
		buf = append(buf, ',')
		buf = append(buf, ' ')
	}

	// Drop the last ", ".
	buf = buf[:len(buf)-2]
	return buf
}

// MarshalJSON returns an JSON formatted string slice (or array).
func (tags Tags) MarshalJSON() ([]byte, error) {
	if len(tags) == 0 {
		return []byte("[]"), nil
	}

	// Add each tag in the form of `"tag", `
	buf := []byte("[")
	for _, tag := range tags {
		qoutedTag := strconv.Quote(tag)
		buf = append(buf, qoutedTag...)
		buf = append(buf, ',')
		buf = append(buf, ' ')
	}

	// Drop the last "," and a closing bracket.
	buf = append(buf[:len(buf)-2], ']')
	return buf, nil
}
<commit_msg>Small doc fix<commit_after>// Copyright (C) 2015 Thomas de Zeeuw.
//
// Licensed under the MIT license that can be found in the LICENSE file.

package logger

import "strconv"

// Tags are keywords usefull in searching through logs, for example:
//
//	tags := Tags{"file.go", "myFn", "user:$user_id", "input:$input"}
//
// With this information you can lookup any logs for a specific user reporting
// an issue. Then you can find which function, in which file, is throwing the
// error.
type Tags []string

// String creates a comma separated list from the tags in string.
func (tags Tags) String() string {
	return string(tags.Bytes())
}

// Bytes does the same as Tags.String, but returns a byte slice.
func (tags Tags) Bytes() []byte {
	if len(tags) == 0 {
		return []byte{}
	}

	// Add each tag in the form of "tag, ".
	var buf []byte
	for _, tag := range tags {
		buf = append(buf, tag...)
		buf = append(buf, ',')
		buf = append(buf, ' ')
	}

	// Drop the last ", ".
	buf = buf[:len(buf)-2]
	return buf
}

// MarshalJSON returns an JSON formatted string slice (or JSON array).
func (tags Tags) MarshalJSON() ([]byte, error) {
	if len(tags) == 0 {
		return []byte("[]"), nil
	}

	// Add each tag in the form of `"tag", `
	buf := []byte("[")
	for _, tag := range tags {
		qoutedTag := strconv.Quote(tag)
		buf = append(buf, qoutedTag...)
		buf = append(buf, ',')
		buf = append(buf, ' ')
	}

	// Drop the last "," and add a closing bracket.
	buf = append(buf[:len(buf)-2], ']')
	return buf, nil
}
<|endoftext|>


<commit_before>// Copyright 2011 Google Inc. All Rights Reserved.
// This file is available under the Apache license.

package main

import (
	"io"
	"log"
	"os"
	"unicode/utf8"
)

type tailer struct {
	Line     chan string         // Logfile lines being emitted.
	changes  chan string         // Notification of changes arriving.
	files    map[string]*os.File // File handles for each pathname.
	partials map[string]string   // Cache of the currently read line before newline from each pathname.
	watcher  *watcher            // Watcher who we inform about new log files.
}

// NewTailer returns a new tailer.
func NewTailer(w *watcher) *tailer {
	return &tailer{
		Line:     make(chan string),
		changes:  make(chan string),
		files:    make(map[string]*os.File),
		partials: make(map[string]string),
		watcher:  w}
}

// Tail adds a file to be tailed.
func (t *tailer) Tail(pathname string) {
	var err error
	t.files[pathname], err = os.Open(pathname)
	if err != nil {
		log.Printf("Failed to open %s for reading: %s\n", pathname, err)
	}
	t.files[pathname].Seek(0, os.SEEK_END)
	if t.watcher != nil {
		t.watcher.WatchLogFile(pathname, t.changes, nil)
	}
}

// Handle notification of a log update from the watcher.
func (t *tailer) handleLogChange(pathname string) {
Loop:
	for {
		b := make([]byte, 32)
		n, err := t.files[pathname].Read(b)
		if err != nil {
			if err == io.EOF && n == 0 {
				// end of file for now, return
				break Loop
			}
			log.Fatal("read failed:", err)
		} else {
			for i, width := 0, 0; i < len(b) && i < n; i += width {
				var rune rune
				rune, width = utf8.DecodeRune(b[i:])
				switch {
				case rune != '\n':
					t.partials[pathname] += string(rune)
				default:
					// send off line
					t.Line <- t.partials[pathname]
					t.partials[pathname] = ""
				}
			}
		}
	}
}

func (t *tailer) start() {
	for {
		select {
		case path := <-t.changes:
			t.handleLogChange(path)
		}
	}
}
<commit_msg>Run handleLogChange in a goroutine, which should add more concurrency for multiple log file updates.<commit_after>// Copyright 2011 Google Inc. All Rights Reserved.
// This file is available under the Apache license.

package main

import (
	"io"
	"log"
	"os"
	"unicode/utf8"
)

type tailer struct {
	Line     chan string         // Logfile lines being emitted.
	changes  chan string         // Notification of changes arriving.
	files    map[string]*os.File // File handles for each pathname.
	partials map[string]string   // Cache of the currently read line before newline from each pathname.
	watcher  *watcher            // Watcher who we inform about new log files.
}

// NewTailer returns a new tailer.
func NewTailer(w *watcher) *tailer {
	return &tailer{
		Line:     make(chan string),
		changes:  make(chan string),
		files:    make(map[string]*os.File),
		partials: make(map[string]string),
		watcher:  w}
}

// Tail adds a file to be tailed.
func (t *tailer) Tail(pathname string) {
	var err error
	t.files[pathname], err = os.Open(pathname)
	if err != nil {
		log.Printf("Failed to open %s for reading: %s\n", pathname, err)
	}
	t.files[pathname].Seek(0, os.SEEK_END)
	if t.watcher != nil {
		t.watcher.WatchLogFile(pathname, t.changes, nil)
	}
}

// Handle notification of a log update from the watcher.
func (t *tailer) handleLogChange(pathname string) {
Loop:
	for {
		b := make([]byte, 32)
		n, err := t.files[pathname].Read(b)
		if err != nil {
			if err == io.EOF && n == 0 {
				// end of file for now, return
				break Loop
			}
			log.Fatal("read failed:", err)
		} else {
			for i, width := 0, 0; i < len(b) && i < n; i += width {
				var rune rune
				rune, width = utf8.DecodeRune(b[i:])
				switch {
				case rune != '\n':
					t.partials[pathname] += string(rune)
				default:
					// send off line
					t.Line <- t.partials[pathname]
					t.partials[pathname] = ""
				}
			}
		}
	}
}

func (t *tailer) start() {
	for {
		select {
		case path := <-t.changes:
			go t.handleLogChange(path)
		}
	}
}
<|endoftext|>


<commit_before>package sarah

import (
	"errors"
	"fmt"
	"github.com/oklahomer/go-sarah/log"
	"golang.org/x/net/context"
	"os"
	"path"
)

var (
	// ErrTaskInsufficientArgument is returned when required parameters are not set.
	ErrTaskInsufficientArgument = errors.New("Identifier and Func must be set.")

	// ErrTaskScheduleNotGiven is returned when schedule is provided by neither ScheduledTaskBuilder's parameter or config.
	ErrTaskScheduleNotGiven = errors.New("Task schedule is not set or given from config struct.")
)

// ScheduledTaskResult is a struct that ScheduledTask returns on its execution.
type ScheduledTaskResult struct {
	Content     interface{}
	Destination OutputDestination
}

// taskFunc is a function type that represents scheduled task.
type taskFunc func(context.Context, ...TaskConfig) ([]*ScheduledTaskResult, error)

// TaskConfig provides an interface that every task configuration must satisfy, which actually means empty.
type TaskConfig interface{}

// ScheduledConfig defines an interface that config with schedule MUST satisfy.
// When no execution schedule is set with ScheduledTaskBuilder.Schedule, this value is taken as default on ScheduledTaskBuilder.Build.
type ScheduledConfig interface {
	Schedule() string
}

// DestinatedConfig defines an interface that config with default destination MUST satisfy.
// When no default output destination is set with ScheduledTaskBuilder.DefaultDestination, this value is taken as default on ScheduledTaskBuilder.Build.
type DestinatedConfig interface {
	DefaultDestination() OutputDestination
}

// ScheduledTask defines interface that all scheduled task MUST satisfy.
// As long as a struct satisfies this interface, the struct can be registered as ScheduledTask via Runner.RegisterScheduledTask.
type ScheduledTask interface {
	Identifier() string
	Execute(context.Context) ([]*ScheduledTaskResult, error)
	DefaultDestination() OutputDestination
	Schedule() string
}

type scheduledTask struct {
	identifier         string
	taskFunc           taskFunc
	schedule           string
	defaultDestination OutputDestination
	config             TaskConfig
}

// Identifier returns unique ID of this task.
func (task *scheduledTask) Identifier() string {
	return task.identifier
}

// Execute executes scheduled task and returns *slice* of results.
//
// Note that scheduled task may result in sending messages to multiple destinations;
// sending taking-out-trash alarm to #dady-chores room while sending go-to-school alarm to #daughter room.
//
// When sending messages to multiple destinations, create and return results as many as destinations.
// If output destination is nil, caller tries to find corresponding destination from config struct.
func (task *scheduledTask) Execute(ctx context.Context) ([]*ScheduledTaskResult, error) {
	return task.taskFunc(ctx, task.config)
}

// Schedule returns execution schedule.
func (task *scheduledTask) Schedule() string {
	return task.schedule
}

// DefaultDestination returns the default output destination of this task.
// OutputDestination returned by task execution has higher priority.
func (task *scheduledTask) DefaultDestination() OutputDestination {
	return task.defaultDestination
}

// ScheduledTaskBuilder is a helper that creates scheduledTask with given parameter.
type ScheduledTaskBuilder struct {
	identifier         string
	taskFunc           taskFunc
	schedule           string
	defaultDestination OutputDestination
	config             TaskConfig
}

// NewScheduledTaskBuilder creates and returns ScheduledTaskBuilder instance.
func NewScheduledTaskBuilder() *ScheduledTaskBuilder {
	return &ScheduledTaskBuilder{}
}

// Identifier sets unique ID of this task.
// This is used to identify re-configure tasks and replace old ones.
func (builder *ScheduledTaskBuilder) Identifier(id string) *ScheduledTaskBuilder {
	builder.identifier = id
	return builder
}

// Func sets function to be called on task execution.
// To set function that requires some sort of configuration struct, use ConfigurableFunc.
func (builder *ScheduledTaskBuilder) Func(fn func(context.Context) ([]*ScheduledTaskResult, error)) *ScheduledTaskBuilder {
	builder.config = nil
	builder.taskFunc = func(ctx context.Context, cfg ...TaskConfig) ([]*ScheduledTaskResult, error) {
		return fn(ctx)
	}
	return builder
}

// Schedule sets execution schedule.
// Representation spec. is identical to that of github.com/robfig/cron.
func (builder *ScheduledTaskBuilder) Schedule(schedule string) *ScheduledTaskBuilder {
	builder.schedule = schedule
	return builder
}

// DefaultDestination sets default output destination of this task.
// OutputDestination returned by task execution has higher priority.
func (builder *ScheduledTaskBuilder) DefaultDestination(dest OutputDestination) *ScheduledTaskBuilder {
	builder.defaultDestination = dest
	return builder
}

// ConfigurableFunc sets function for ScheduledTask with configuration struct.
// Passed configuration struct is passed to function as a third argument.
//
// When this builder is stashed via StashScheduledTaskBuilder and Runner runs with Config.PluginConfigRoot,
// configuration struct gets updated automatically when corresponding configuration file is modified.
func (builder *ScheduledTaskBuilder) ConfigurableFunc(config TaskConfig, fn func(context.Context, TaskConfig) ([]*ScheduledTaskResult, error)) *ScheduledTaskBuilder {
	builder.config = config
	builder.taskFunc = func(ctx context.Context, cfg ...TaskConfig) ([]*ScheduledTaskResult, error) {
		return fn(ctx, cfg[0])
	}
	return builder
}

// Build creates instance of scheduledTask with given parameters.
func (builder *ScheduledTaskBuilder) Build(configDir string) (ScheduledTask, error) {
	if builder.identifier == "" || builder.taskFunc == nil {
		return nil, ErrTaskInsufficientArgument
	}

	// If path to the configuration files' directory is given, corresponding configuration file MAY exist.
	// If exists, read and map to given config struct; if file does not exist, assume the config struct is already configured by developer.
	taskConfig := builder.config
	if configDir != "" && taskConfig != nil {
		fileName := builder.identifier + ".yaml"
		configPath := path.Join(configDir, fileName)
		err := readConfig(configPath, taskConfig)
		if err != nil && os.IsNotExist(err) {
			log.Infof("config struct is set, but there was no corresponding setting file at %s. "+
				"assume config struct is already filled with appropriate value and keep going. command ID: %s.",
				configPath, builder.identifier)
		} else if err != nil {
			// File was there, but could not read.
			return nil, err
		}
	}

	// Setup execution schedule
	schedule := builder.schedule
	if taskConfig != nil {
		if scheduledConfig, ok := (taskConfig).(ScheduledConfig); ok {
			if s := scheduledConfig.Schedule(); s != "" {
				schedule = s
			}
		}
	}
	if schedule == "" {
		return nil, ErrTaskScheduleNotGiven
	}

	// Setup default destination
	// This can be nil since each task execution may return corresponding destination
	dest := builder.defaultDestination
	if taskConfig != nil {
		if destConfig, ok := (taskConfig).(DestinatedConfig); ok {
			if d := destConfig.DefaultDestination(); d != nil {
				dest = d
			}
		}
	}

	return &scheduledTask{
		identifier:         builder.identifier,
		taskFunc:           builder.taskFunc,
		schedule:           schedule,
		defaultDestination: dest,
		config:             builder.config,
	}, nil
}

// MustBuild is like Build but panics if any error occurs on Build.
// It simplifies safe initialization of global variables holding built Command instances.
func (builder *ScheduledTaskBuilder) MustBuild() ScheduledTask {
	task, err := builder.Build("")
	if err != nil {
		panic(fmt.Sprintf("Error on building task: %s", err.Error()))
	}

	return task
}
<commit_msg>Fix typo<commit_after>package sarah

import (
	"errors"
	"fmt"
	"github.com/oklahomer/go-sarah/log"
	"golang.org/x/net/context"
	"os"
	"path"
)

var (
	// ErrTaskInsufficientArgument is returned when required parameters are not set.
	ErrTaskInsufficientArgument = errors.New("Identifier and Func must be set.")

	// ErrTaskScheduleNotGiven is returned when schedule is provided by neither ScheduledTaskBuilder's parameter nor config.
	ErrTaskScheduleNotGiven = errors.New("Task schedule is not set or given from config struct.")
)

// ScheduledTaskResult is a struct that ScheduledTask returns on its execution.
type ScheduledTaskResult struct {
	Content     interface{}
	Destination OutputDestination
}

// taskFunc is a function type that represents scheduled task.
type taskFunc func(context.Context, ...TaskConfig) ([]*ScheduledTaskResult, error)

// TaskConfig provides an interface that every task configuration must satisfy, which actually means empty.
type TaskConfig interface{}

// ScheduledConfig defines an interface that config with schedule MUST satisfy.
// When no execution schedule is set with ScheduledTaskBuilder.Schedule, this value is taken as default on ScheduledTaskBuilder.Build.
type ScheduledConfig interface {
	Schedule() string
}

// DestinatedConfig defines an interface that config with default destination MUST satisfy.
// When no default output destination is set with ScheduledTaskBuilder.DefaultDestination, this value is taken as default on ScheduledTaskBuilder.Build.
type DestinatedConfig interface {
	DefaultDestination() OutputDestination
}

// ScheduledTask defines interface that all scheduled task MUST satisfy.
// As long as a struct satisfies this interface, the struct can be registered as ScheduledTask via Runner.RegisterScheduledTask.
type ScheduledTask interface {
	Identifier() string
	Execute(context.Context) ([]*ScheduledTaskResult, error)
	DefaultDestination() OutputDestination
	Schedule() string
}

type scheduledTask struct {
	identifier         string
	taskFunc           taskFunc
	schedule           string
	defaultDestination OutputDestination
	config             TaskConfig
}

// Identifier returns unique ID of this task.
func (task *scheduledTask) Identifier() string {
	return task.identifier
}

// Execute executes scheduled task and returns *slice* of results.
//
// Note that scheduled task may result in sending messages to multiple destinations;
// sending taking-out-trash alarm to #dady-chores room while sending go-to-school alarm to #daughter room.
//
// When sending messages to multiple destinations, create and return results as many as destinations.
// If output destination is nil, caller tries to find corresponding destination from config struct.
func (task *scheduledTask) Execute(ctx context.Context) ([]*ScheduledTaskResult, error) {
	return task.taskFunc(ctx, task.config)
}

// Schedule returns execution schedule.
func (task *scheduledTask) Schedule() string {
	return task.schedule
}

// DefaultDestination returns the default output destination of this task.
// OutputDestination returned by task execution has higher priority.
func (task *scheduledTask) DefaultDestination() OutputDestination {
	return task.defaultDestination
}

// ScheduledTaskBuilder is a helper that creates scheduledTask with given parameter.
type ScheduledTaskBuilder struct {
	identifier         string
	taskFunc           taskFunc
	schedule           string
	defaultDestination OutputDestination
	config             TaskConfig
}

// NewScheduledTaskBuilder creates and returns ScheduledTaskBuilder instance.
func NewScheduledTaskBuilder() *ScheduledTaskBuilder {
	return &ScheduledTaskBuilder{}
}

// Identifier sets unique ID of this task.
// This is used to identify re-configure tasks and replace old ones.
func (builder *ScheduledTaskBuilder) Identifier(id string) *ScheduledTaskBuilder {
	builder.identifier = id
	return builder
}

// Func sets function to be called on task execution.
// To set function that requires some sort of configuration struct, use ConfigurableFunc.
func (builder *ScheduledTaskBuilder) Func(fn func(context.Context) ([]*ScheduledTaskResult, error)) *ScheduledTaskBuilder {
	builder.config = nil
	builder.taskFunc = func(ctx context.Context, cfg ...TaskConfig) ([]*ScheduledTaskResult, error) {
		return fn(ctx)
	}
	return builder
}

// Schedule sets execution schedule.
// Representation spec. is identical to that of github.com/robfig/cron.
func (builder *ScheduledTaskBuilder) Schedule(schedule string) *ScheduledTaskBuilder {
	builder.schedule = schedule
	return builder
}

// DefaultDestination sets default output destination of this task.
// OutputDestination returned by task execution has higher priority.
func (builder *ScheduledTaskBuilder) DefaultDestination(dest OutputDestination) *ScheduledTaskBuilder {
	builder.defaultDestination = dest
	return builder
}

// ConfigurableFunc sets function for ScheduledTask with configuration struct.
// Passed configuration struct is passed to function as a third argument.
//
// When this builder is stashed via StashScheduledTaskBuilder and Runner runs with Config.PluginConfigRoot,
// configuration struct gets updated automatically when corresponding configuration file is modified.
func (builder *ScheduledTaskBuilder) ConfigurableFunc(config TaskConfig, fn func(context.Context, TaskConfig) ([]*ScheduledTaskResult, error)) *ScheduledTaskBuilder {
	builder.config = config
	builder.taskFunc = func(ctx context.Context, cfg ...TaskConfig) ([]*ScheduledTaskResult, error) {
		return fn(ctx, cfg[0])
	}
	return builder
}

// Build creates instance of scheduledTask with given parameters.
func (builder *ScheduledTaskBuilder) Build(configDir string) (ScheduledTask, error) {
	if builder.identifier == "" || builder.taskFunc == nil {
		return nil, ErrTaskInsufficientArgument
	}

	// If path to the configuration files' directory is given, corresponding configuration file MAY exist.
	// If exists, read and map to given config struct; if file does not exist, assume the config struct is already configured by developer.
	taskConfig := builder.config
	if configDir != "" && taskConfig != nil {
		fileName := builder.identifier + ".yaml"
		configPath := path.Join(configDir, fileName)
		err := readConfig(configPath, taskConfig)
		if err != nil && os.IsNotExist(err) {
			log.Infof("config struct is set, but there was no corresponding setting file at %s. "+
				"assume config struct is already filled with appropriate value and keep going. command ID: %s.",
				configPath, builder.identifier)
		} else if err != nil {
			// File was there, but could not read.
			return nil, err
		}
	}

	// Setup execution schedule
	schedule := builder.schedule
	if taskConfig != nil {
		if scheduledConfig, ok := (taskConfig).(ScheduledConfig); ok {
			if s := scheduledConfig.Schedule(); s != "" {
				schedule = s
			}
		}
	}
	if schedule == "" {
		return nil, ErrTaskScheduleNotGiven
	}

	// Setup default destination
	// This can be nil since each task execution may return corresponding destination
	dest := builder.defaultDestination
	if taskConfig != nil {
		if destConfig, ok := (taskConfig).(DestinatedConfig); ok {
			if d := destConfig.DefaultDestination(); d != nil {
				dest = d
			}
		}
	}

	return &scheduledTask{
		identifier:         builder.identifier,
		taskFunc:           builder.taskFunc,
		schedule:           schedule,
		defaultDestination: dest,
		config:             builder.config,
	}, nil
}

// MustBuild is like Build but panics if any error occurs on Build.
// It simplifies safe initialization of global variables holding built Command instances.
func (builder *ScheduledTaskBuilder) MustBuild() ScheduledTask {
	task, err := builder.Build("")
	if err != nil {
		panic(fmt.Sprintf("Error on building task: %s", err.Error()))
	}

	return task
}
<|endoftext|>


<commit_before>package util

import (
	"github.com/realglobe-Inc/go-lib-rg/erro"
	"net"
	"net/http"
	"strconv"
)

func FreePort() (port int, err error) {
	lis, err := net.Listen("tcp", ":0")
	if err != nil {
		return 0, erro.Wrap(err)
	}
	lis.Close()

	_, portStr, err := net.SplitHostPort(lis.Addr().String())
	if err != nil {
		return 0, erro.Wrap(err)
	}

	port, err = strconv.Atoi(portStr)
	if err != nil {
		return 0, erro.Wrap(err)
	}

	return port, nil
}

// テスト用の HTTP サーバー。
type TestHttpServer struct {
	lis    net.Listener
	respCh chan *testHttpServerResponse
}

type testHttpServerResponse struct {
	status int
	header http.Header
	body   []byte
}

func NewTestHttpServer(port, chCap int) (*TestHttpServer, error) {
	lis, err := net.Listen("tcp", ":"+strconv.Itoa(port))
	if err != nil {
		return nil, erro.Wrap(err)
	}

	respCh := make(chan *testHttpServerResponse, chCap)

	mux := http.NewServeMux()
	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		resp := <-respCh
		for key, values := range resp.header {
			for _, value := range values {
				w.Header().Add(key, value)
			}
		}
		w.WriteHeader(resp.status)
		if resp.body != nil {
			w.Write(resp.body)
		}
	})

	go func() {
		http.Serve(lis, mux)
	}()

	return &TestHttpServer{lis, respCh}, nil
}

// 次に返させるレスポンスを与える。
func (server *TestHttpServer) AddResponse(status int, header http.Header, body []byte) {
	server.respCh <- &testHttpServerResponse{status, header, body}
}

// 待ち受けソケットを閉じる。
func (server *TestHttpServer) Close() error {
	if err := server.lis.Close(); err != nil {
		return erro.Wrap(err)
	}
	return nil
}
<commit_msg>テスト用 HTTP サーバーにリクエストの取り出し機能を追加<commit_after>package util

import (
	"github.com/realglobe-Inc/go-lib-rg/erro"
	"net"
	"net/http"
	"strconv"
)

func FreePort() (port int, err error) {
	lis, err := net.Listen("tcp", ":0")
	if err != nil {
		return 0, erro.Wrap(err)
	}
	lis.Close()

	_, portStr, err := net.SplitHostPort(lis.Addr().String())
	if err != nil {
		return 0, erro.Wrap(err)
	}

	port, err = strconv.Atoi(portStr)
	if err != nil {
		return 0, erro.Wrap(err)
	}

	return port, nil
}

// テスト用の HTTP サーバー。
type TestHttpServer struct {
	lis    net.Listener
	respCh chan *testHttpServerResponse
}

type testHttpServerResponse struct {
	status int
	header http.Header
	body   []byte

	reqCh chan<- *http.Request
}

func NewTestHttpServer(port, chCap int) (*TestHttpServer, error) {
	lis, err := net.Listen("tcp", ":"+strconv.Itoa(port))
	if err != nil {
		return nil, erro.Wrap(err)
	}

	respCh := make(chan *testHttpServerResponse, chCap)

	mux := http.NewServeMux()
	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		resp := <-respCh
		resp.reqCh <- r
		for key, values := range resp.header {
			for _, value := range values {
				w.Header().Add(key, value)
			}
		}
		w.WriteHeader(resp.status)
		if resp.body != nil {
			w.Write(resp.body)
		}
	})

	go func() {
		http.Serve(lis, mux)
	}()

	return &TestHttpServer{lis, respCh}, nil
}

// 次に返させるレスポンスを与える。
func (server *TestHttpServer) AddResponse(status int, header http.Header, body []byte) <-chan *http.Request {
	reqCh := make(chan *http.Request, 1)
	server.respCh <- &testHttpServerResponse{status, header, body, reqCh}
	return reqCh
}

// 待ち受けソケットを閉じる。
func (server *TestHttpServer) Close() error {
	if err := server.lis.Close(); err != nil {
		return erro.Wrap(err)
	}
	return nil
}
<|endoftext|>


<commit_before>package main

import (
    "reflect"
    "fmt"
    "unsafe"
    "time"
    "github.com/BluePecker/JwtAuth/storage"
    _ "github.com/BluePecker/JwtAuth/storage/redis"
)

type Hand struct {

}

type Foot struct {
    K string
}

func (f *Foot) Hi() {
    fmt.Println("fh")
}

type User struct {
    Name string
    //Hand *Hand
    Foot *Foot
}

func (u *User) Ec() string {
    fmt.Println("ec")
    return "ec"
}

type G struct {
    Name string
}

func (g *G) E() {
    *g = G{
        Name: "shuc",
    }
}

func main() {
    user := &User{
        Name: "SC",
    }

    fmt.Printf("测试: %+v", (*struct {
        Ne  string
        Age int
        H   int
    })(unsafe.Pointer(user)))

    fmt.Println(reflect.ValueOf(*user).FieldByName("Foot"))

    fmt.Println(reflect.New(reflect.ValueOf(*user).Type()))

    redis, err := storage.NewManager("redis", storage.Options{
        Host: "127.0.0.1",
        Port: 6379,
        PoolSize: 20,
    });

    if err != nil {
        fmt.Println(err)
    }

    redis.Write("jwt", "13658009009", 0)
    redis.Write("auth", "13658009009", 30)

    fmt.Println("redis ttl: ", redis.TTL("jwt"))
    fmt.Println("redis ttl: ", redis.TTL("auth"))
    v, err := redis.ReadString("jwt")
    fmt.Println("redis ttl: ", v, err)
    v, err = redis.ReadString("auth")
    fmt.Println("redis ttl: ", v, err)

    store := &storage.MemStore{}

    //store.SetImmutable("name", "shuchao", 3)
    store.Set("name", "hi", 2)

    fmt.Println(store)
    time.Sleep(time.Duration(1 * time.Second))
    fmt.Println(store)

    store.Set("name", "me", 0)
    fmt.Println(store)
    time.Sleep(time.Duration(5000 * time.Second))
    fmt.Println(store)
}

<commit_msg>redis driver<commit_after>package main

import (
    "reflect"
    "fmt"
    "unsafe"
    "github.com/BluePecker/JwtAuth/storage"
    _ "github.com/BluePecker/JwtAuth/storage/redis"
)

type Hand struct {

}

type Foot struct {
    K string
}

func (f *Foot) Hi() {
    fmt.Println("fh")
}

type User struct {
    Name string
    //Hand *Hand
    Foot *Foot
}

func (u *User) Ec() string {
    fmt.Println("ec")
    return "ec"
}

type G struct {
    Name string
}

func (g *G) E() {
    *g = G{
        Name: "shuc",
    }
}

func main() {
    user := &User{
        Name: "SC",
    }

    fmt.Printf("测试: %+v", (*struct {
        Ne  string
        Age int
        H   int
    })(unsafe.Pointer(user)))

    fmt.Println(reflect.ValueOf(*user).FieldByName("Foot"))

    fmt.Println(reflect.New(reflect.ValueOf(*user).Type()))

    redis, err := storage.NewManager("redis", storage.Options{
        Host: "127.0.0.1",
        Port: 6379,
        PoolSize: 20,
    });

    if err != nil {
        fmt.Println(err)
    }

    redis.Write("jwt", "13658009009", 0)
    redis.Write("auth", "23658009009", 30)

    fmt.Println("redis ttl: ", redis.TTL("jwt"))
    fmt.Println("redis ttl: ", redis.TTL("auth"))
    v, err := redis.ReadString("jwt")
    fmt.Println("redis ttl: ", v, err)
    v, err = redis.ReadString("auth")
    fmt.Println("redis ttl: ", v, err)

    //store := &storage.MemStore{}
    //
    ////store.SetImmutable("name", "shuchao", 3)
    //store.Set("name", "hi", 2)
    //
    //fmt.Println(store)
    //time.Sleep(time.Duration(1 * time.Second))
    //fmt.Println(store)
    //
    //store.Set("name", "me", 0)
    //fmt.Println(store)
    //time.Sleep(time.Duration(5000 * time.Second))
    //fmt.Println(store)
}

<|endoftext|>