<commit_before>package gkvlite

import (
	"sync/atomic"
	"unsafe"
)

var reclaimable_node = &node{} // Sentinel.

func (t *Collection) markReclaimable(n *node) {
	if n == nil || n.next != nil || n == reclaimable_node {
		return
	}
	n.next = reclaimable_node // Use next pointer as sentinel.
}

func (t *Collection) reclaimNodes(n *node) {
	if n == nil {
		return
	}
	if n.next != reclaimable_node {
		return
	}
	var left *node
	var right *node
	if !n.left.isEmpty() {
		left = n.left.Node()
	}
	if !n.right.isEmpty() {
		right = n.right.Node()
	}
	t.freeNode(n)
	t.reclaimNodes(left)
	t.reclaimNodes(right)
}

// Assumes that the caller serializes invocations.
func (t *Collection) mkNode(itemIn *itemLoc, leftIn *nodeLoc, rightIn *nodeLoc,
	numNodesIn uint64, numBytesIn uint64) *node {
	t.stats.MkNodes++
	t.freeLock.Lock()
	n := t.freeNodes
	if n == nil {
		t.freeLock.Unlock()
		atomic.AddUint64(&t.store.nodeAllocs, 1)
		t.stats.AllocNodes++
		n = &node{}
	} else {
		t.freeNodes = n.next
		t.freeLock.Unlock()
	}
	n.item.Copy(itemIn)
	n.left.Copy(leftIn)
	n.right.Copy(rightIn)
	n.numNodes = numNodesIn
	n.numBytes = numBytesIn
	n.next = nil
	return n
}

func (t *Collection) freeNode(n *node) {
	if n == nil || n == reclaimable_node {
		return
	}
	if n.next != nil && n.next != reclaimable_node {
		panic("double free node")
	}
	n.item = *empty_itemLoc
	n.left = *empty_nodeLoc
	n.right = *empty_nodeLoc
	n.numNodes = 0
	n.numBytes = 0

	t.freeLock.Lock()
	n.next = t.freeNodes
	t.freeNodes = n
	t.stats.FreeNodes++
	t.freeLock.Unlock()
}

// Assumes that the caller serializes invocations.
func (t *Collection) mkNodeLoc(n *node) *nodeLoc {
	t.stats.MkNodeLocs++
	nloc := t.freeNodeLocs
	if nloc == nil {
		t.stats.AllocNodeLocs++
		nloc = &nodeLoc{}
	}
	t.freeNodeLocs = nloc.next
	nloc.loc = unsafe.Pointer(nil)
	nloc.node = unsafe.Pointer(n)
	nloc.next = nil
	return nloc
}

// Assumes that the caller serializes invocations.
func (t *Collection) freeNodeLoc(nloc *nodeLoc) {
	if nloc == nil || nloc == empty_nodeLoc {
		return
	}
	if nloc.next != nil {
		panic("double free nloc")
	}
	t.stats.FreeNodeLocs++
	nloc.loc = unsafe.Pointer(nil)
	nloc.node = unsafe.Pointer(nil)
	nloc.next = t.freeNodeLocs
	t.freeNodeLocs = nloc
}

func (t *Collection) mkRootNodeLoc(root *nodeLoc) *rootNodeLoc {
	t.freeLock.Lock()
	rnl := t.freeRootNodeLocs
	if rnl == nil {
		t.freeLock.Unlock()
		rnl = &rootNodeLoc{}
	} else {
		t.freeRootNodeLocs = rnl.next
		t.freeLock.Unlock()
	}
	rnl.refs = 1
	rnl.root = root
	rnl.next = nil
	return rnl
}

func (t *Collection) freeRootNodeLoc(rnl *rootNodeLoc) {
	if rnl == nil {
		return
	}
	rnl.refs = 0
	rnl.root = nil

	t.freeLock.Lock()
	rnl.next = t.freeRootNodeLocs
	t.freeRootNodeLocs = rnl
	t.freeLock.Unlock()
}
<commit_msg>Turn off reclaimation for now.<commit_after>package gkvlite

import (
	"sync/atomic"
	"unsafe"
)

var reclaimable_node = &node{} // Sentinel.

func (t *Collection) markReclaimable(n *node) {
	if n == nil || n.next != nil || n == reclaimable_node {
		return
	}
	n.next = reclaimable_node // Use next pointer as sentinel.
}

func (t *Collection) reclaimNodes(n *node) {
	if n == nil {
		return
	}
	if n.next != reclaimable_node {
		return
	}
	var left *node
	var right *node
	if !n.left.isEmpty() {
		left = n.left.Node()
	}
	if !n.right.isEmpty() {
		right = n.right.Node()
	}
	t.freeNode(n)
	t.reclaimNodes(left)
	t.reclaimNodes(right)
}

// Assumes that the caller serializes invocations.
func (t *Collection) mkNode(itemIn *itemLoc, leftIn *nodeLoc, rightIn *nodeLoc,
	numNodesIn uint64, numBytesIn uint64) *node {
	t.stats.MkNodes++
	t.freeLock.Lock()
	n := t.freeNodes
	if n == nil {
		t.freeLock.Unlock()
		atomic.AddUint64(&t.store.nodeAllocs, 1)
		t.stats.AllocNodes++
		n = &node{}
	} else {
		t.freeNodes = n.next
		t.freeLock.Unlock()
	}
	n.item.Copy(itemIn)
	n.left.Copy(leftIn)
	n.right.Copy(rightIn)
	n.numNodes = numNodesIn
	n.numBytes = numBytesIn
	n.next = nil
	return n
}

func (t *Collection) freeNode(n *node) {
	return

	if n == nil || n == reclaimable_node {
		return
	}
	if n.next != nil && n.next != reclaimable_node {
		panic("double free node")
	}
	n.item = *empty_itemLoc
	n.left = *empty_nodeLoc
	n.right = *empty_nodeLoc
	n.numNodes = 0
	n.numBytes = 0

	t.freeLock.Lock()
	n.next = t.freeNodes
	t.freeNodes = n
	t.stats.FreeNodes++
	t.freeLock.Unlock()
}

// Assumes that the caller serializes invocations.
func (t *Collection) mkNodeLoc(n *node) *nodeLoc {
	t.stats.MkNodeLocs++
	nloc := t.freeNodeLocs
	if nloc == nil {
		t.stats.AllocNodeLocs++
		nloc = &nodeLoc{}
	}
	t.freeNodeLocs = nloc.next
	nloc.loc = unsafe.Pointer(nil)
	nloc.node = unsafe.Pointer(n)
	nloc.next = nil
	return nloc
}

// Assumes that the caller serializes invocations.
func (t *Collection) freeNodeLoc(nloc *nodeLoc) {
	return

	if nloc == nil || nloc == empty_nodeLoc {
		return
	}
	if nloc.next != nil {
		panic("double free nloc")
	}
	t.stats.FreeNodeLocs++
	nloc.loc = unsafe.Pointer(nil)
	nloc.node = unsafe.Pointer(nil)
	nloc.next = t.freeNodeLocs
	t.freeNodeLocs = nloc
}

func (t *Collection) mkRootNodeLoc(root *nodeLoc) *rootNodeLoc {
	t.freeLock.Lock()
	rnl := t.freeRootNodeLocs
	if rnl == nil {
		t.freeLock.Unlock()
		rnl = &rootNodeLoc{}
	} else {
		t.freeRootNodeLocs = rnl.next
		t.freeLock.Unlock()
	}
	rnl.refs = 1
	rnl.root = root
	rnl.next = nil
	return rnl
}

func (t *Collection) freeRootNodeLoc(rnl *rootNodeLoc) {
	return

	if rnl == nil {
		return
	}
	rnl.refs = 0
	rnl.root = nil

	t.freeLock.Lock()
	rnl.next = t.freeRootNodeLocs
	t.freeRootNodeLocs = rnl
	t.freeLock.Unlock()
}
<|endoftext|>


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

package main

import (
	"bytes"
	"errors"
	"fmt"
	"github.com/globocom/tsuru/cmd"
	"github.com/globocom/tsuru/fs"
	"io/ioutil"
	"net/http"
	"os"
	"os/user"
	"strings"
)

type keyReader struct {
	fsystem fs.Fs
}

func (r *keyReader) fs() fs.Fs {
	if r.fsystem == nil {
		r.fsystem = fs.OsFs{}
	}
	return r.fsystem
}

func getKeyPath(args []string) (string, error) {
	if len(args) > 0 {
		return args[0], nil
	}
	user, err := user.Current()
	if err != nil {
		return "", err
	}
	return user.HomeDir + "/.ssh/id_rsa.pub", nil
}

func (r *keyReader) readKey(keyPath string) (string, error) {
	f, err := r.fs().Open(keyPath)
	if err != nil {
		return "", err
	}
	defer f.Close()
	output, err := ioutil.ReadAll(f)
	return string(output), err
}

func (r *keyReader) fileNotFound(context *cmd.Context) error {
	if len(context.Args) > 0 {
		msg := fmt.Sprintf("File %s does not exist!", context.Args[0])
		fmt.Fprint(context.Stderr, msg+"\n")
		return errors.New(msg)
	}
	msg := "You don't have a public key\nTo generate a key use 'ssh-keygen' command\n"
	fmt.Fprint(context.Stderr, msg)
	return errors.New("You need to have a public rsa key")
}

type KeyRemove struct {
	keyReader
}

func (c *KeyRemove) Info() *cmd.Info {
	return &cmd.Info{
		Name:  "key-remove",
		Usage: "key-remove [path/to/key/file.pub]",
		Desc:  "remove your public key ($HOME/.id_rsa.pub by default).",
	}
}

func (c *KeyRemove) Run(context *cmd.Context, client cmd.Doer) error {
	keyPath, err := getKeyPath(context.Args)
	if err != nil {
		return err
	}
	key, err := c.readKey(keyPath)
	if os.IsNotExist(err) {
		return c.fileNotFound(context)
	}
	b := bytes.NewBufferString(fmt.Sprintf(`{"key":"%s"}`, strings.Replace(key, "\n", "", -1)))
	request, err := http.NewRequest("DELETE", cmd.GetUrl("/users/keys"), b)
	if err != nil {
		return err
	}
	_, err = client.Do(request)
	if err != nil {
		return err
	}
	fmt.Fprint(context.Stdout, "Key successfully removed!\n")
	return nil
}

type KeyAdd struct {
	keyReader
}

func (c *KeyAdd) Info() *cmd.Info {
	return &cmd.Info{
		Name:  "key-add",
		Usage: "key-add [path/to/key/file.pub]",
		Desc:  "add your public key ($HOME/.ssh/id_rsa.pub by default).",
	}
}

func (c *KeyAdd) Run(context *cmd.Context, client cmd.Doer) error {
	keyPath, err := getKeyPath(context.Args)
	if err != nil {
		return err
	}
	key, err := c.readKey(keyPath)
	if os.IsNotExist(err) {
		return c.fileNotFound(context)
	}
	b := bytes.NewBufferString(fmt.Sprintf(`{"key":"%s"}`, strings.Replace(key, "\n", "", -1)))
	request, err := http.NewRequest("POST", cmd.GetUrl("/users/keys"), b)
	if err != nil {
		return err
	}
	_, err = client.Do(request)
	if err != nil {
		return err
	}
	fmt.Fprint(context.Stdout, "Key successfully added!\n")
	return nil
}
<commit_msg>cmd, cmd/tsuru/developer: don't use user.Current<commit_after>// Copyright 2012 tsuru authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"bytes"
	"errors"
	"fmt"
	"github.com/globocom/tsuru/cmd"
	"github.com/globocom/tsuru/fs"
	"io/ioutil"
	"net/http"
	"os"
	"strings"
)

type keyReader struct {
	fsystem fs.Fs
}

func (r *keyReader) fs() fs.Fs {
	if r.fsystem == nil {
		r.fsystem = fs.OsFs{}
	}
	return r.fsystem
}

func getKeyPath(args []string) (string, error) {
	if len(args) > 0 {
		return args[0], nil
	}
	home := os.ExpandEnv("$HOME")
	return home + "/.ssh/id_rsa.pub", nil
}

func (r *keyReader) readKey(keyPath string) (string, error) {
	f, err := r.fs().Open(keyPath)
	if err != nil {
		return "", err
	}
	defer f.Close()
	output, err := ioutil.ReadAll(f)
	return string(output), err
}

func (r *keyReader) fileNotFound(context *cmd.Context) error {
	if len(context.Args) > 0 {
		msg := fmt.Sprintf("File %s does not exist!", context.Args[0])
		fmt.Fprint(context.Stderr, msg+"\n")
		return errors.New(msg)
	}
	msg := "You don't have a public key\nTo generate a key use 'ssh-keygen' command\n"
	fmt.Fprint(context.Stderr, msg)
	return errors.New("You need to have a public rsa key")
}

type KeyRemove struct {
	keyReader
}

func (c *KeyRemove) Info() *cmd.Info {
	return &cmd.Info{
		Name:  "key-remove",
		Usage: "key-remove [path/to/key/file.pub]",
		Desc:  "remove your public key ($HOME/.id_rsa.pub by default).",
	}
}

func (c *KeyRemove) Run(context *cmd.Context, client cmd.Doer) error {
	keyPath, err := getKeyPath(context.Args)
	if err != nil {
		return err
	}
	key, err := c.readKey(keyPath)
	if os.IsNotExist(err) {
		return c.fileNotFound(context)
	}
	b := bytes.NewBufferString(fmt.Sprintf(`{"key":"%s"}`, strings.Replace(key, "\n", "", -1)))
	request, err := http.NewRequest("DELETE", cmd.GetUrl("/users/keys"), b)
	if err != nil {
		return err
	}
	_, err = client.Do(request)
	if err != nil {
		return err
	}
	fmt.Fprint(context.Stdout, "Key successfully removed!\n")
	return nil
}

type KeyAdd struct {
	keyReader
}

func (c *KeyAdd) Info() *cmd.Info {
	return &cmd.Info{
		Name:  "key-add",
		Usage: "key-add [path/to/key/file.pub]",
		Desc:  "add your public key ($HOME/.ssh/id_rsa.pub by default).",
	}
}

func (c *KeyAdd) Run(context *cmd.Context, client cmd.Doer) error {
	keyPath, err := getKeyPath(context.Args)
	if err != nil {
		return err
	}
	key, err := c.readKey(keyPath)
	if os.IsNotExist(err) {
		return c.fileNotFound(context)
	}
	b := bytes.NewBufferString(fmt.Sprintf(`{"key":"%s"}`, strings.Replace(key, "\n", "", -1)))
	request, err := http.NewRequest("POST", cmd.GetUrl("/users/keys"), b)
	if err != nil {
		return err
	}
	_, err = client.Do(request)
	if err != nil {
		return err
	}
	fmt.Fprint(context.Stdout, "Key successfully added!\n")
	return nil
}
<|endoftext|>


<commit_before>package device

import (
	"fmt"
	"log"
	"path/filepath"
	"sync"
	"time"

	"github.com/jochenvg/go-udev"
	"github.com/tarm/serial"
)

// Manager manages devices that are plugged into the system. It supports auto
// detection of devices.
//
// Serial ports are opened each for a device, and a clean API for communicating
// is provided via Read, Write and Flush methods.
//
// The devices are monitored via udev, and any changes that requires reloading
// of the  ports are handled by reloading the ports to the devices.
//
// This is safe to use concurrently in multiple goroutines
type Manager struct {
	devices map[string]serial.Config
	conn    []*Conn
	mu      sync.RWMutex
	monitor *udev.Monitor
	done    chan struct{}
	stop    chan struct{}
}

// New returns a new Manager instance
func New() *Manager {
	return &Manager{
		devices: make(map[string]serial.Config),
		done:    make(chan struct{}),
		stop:    make(chan struct{}),
	}
}

// Init initializes the manager. This involves creating a new goroutine to watch
// over the changes detected by udev for any device interaction with the system.
//
// The only interesting device actions are add and reomove for adding and
// removing devices respctively.
func (m *Manager) Init() {
	u := udev.Udev{}
	monitor := u.NewMonitorFromNetlink("udev")
	monitor.FilterAddMatchTag("systemd")
	devCh, err := monitor.DeviceChan(m.done)
	if err != nil {
		panic(err)
	}
	m.monitor = monitor
	go func() {
	stop:
		for {
			select {
			case d := <-devCh:
				switch d.Action() {
				case "add":
					dpath := filepath.Join("/dev", filepath.Base(d.Devpath()))
					m.AddDevice(dpath)
					fmt.Printf(" new device added  %s\n", dpath)
					m.reload()
				case "remove":
					dpath := filepath.Join("/dev", filepath.Base(d.Devpath()))
					fmt.Printf(" %s was removed\n", dpath)
					m.RemoveDevice(dpath)
					m.reload()
				default:
					fmt.Println(d.Action())
				}
			case quit := <-m.stop:
				m.done <- quit
				break stop
			}
		}
	}()
}

// AddDevice adds device name to the manager
func (m *Manager) AddDevice(name string) error {
	cfg := serial.Config{Name: name, Baud: 9600, ReadTimeout: time.Second}
	m.mu.Lock()
	m.devices[name] = cfg
	m.mu.Unlock()
	return nil
}

// RemoveDevice removes device name from the manager
func (m *Manager) RemoveDevice(name string) error {
	m.mu.RLock()
	delete(m.devices, name)
	m.mu.RUnlock()
	return nil
}

// close all ports that are open for the devices
func (m *Manager) releaseAllPorts() {
	for _, c := range m.conn {
		err := c.Close()
		if err != nil {
			log.Printf("[ERR] closing port %s %v\n", c.device.Name, err)
		}
	}
}

func (m *Manager) reload() {
	m.releaseAllPorts()
	var conns []*Conn
	for _, v := range m.devices {
		conn := &Conn{device: v}
		imei, err := conn.Exec("AT+GSN \r")
		if err != nil {
			log.Printf("[ERR] closing port %s %v\n", v.Name, err)
			_ = conn.Close()
			continue
		}
		fmt.Printf(" EMEI %s \n", string(imei))
		conns = append(conns, conn)
	}
	m.conn = conns
}

//Close shuts down the device manager. This makes sure the udev monitor is
//closed and all goroutines are properly exited.
func (m *Manager) Close() {
	m.stop <- struct{}{}
}

// Conn is a device serial connection
type Conn struct {
	device serial.Config
	port   *serial.Port
	isOpen bool
}

// Open opens a serial port to the undelying device
func (c *Conn) Open() error {
	p, err := serial.OpenPort(&c.device)
	if err != nil {
		return err
	}
	c.port = p
	c.isOpen = true
	return nil
}

// Close closes the port helt by *Conn.
func (c *Conn) Close() error {
	if c.isOpen {
		return c.port.Close()
	}
	return nil
}

// Write wites b to the serieal port
func (c *Conn) Write(b []byte) (int, error) {
	return c.port.Write(b)
}

// Read reads from serial port
func (c *Conn) Read(b []byte) (int, error) {
	return c.port.Read(b)
}

// Exec sends the command over serial port and rrturns the response. If the port
// is closed it is opened  before sending the command.
func (c *Conn) Exec(cmd string) ([]byte, error) {
	if !c.isOpen {
		fmt.Println("Opening port")
		err := c.Open()
		if err != nil {
			return nil, err
		}
	}
	defer func() { _ = c.port.Flush() }()
	_, err := c.Write([]byte(cmd))
	if err != nil {
		return nil, err
	}
	fmt.Println("done writing")
	fmt.Println("READING")
	buf := make([]byte, 128)
	_, err = c.Read(buf)
	if err != nil {
		return nil, err
	}
	fmt.Println("done reading")
	return buf, nil
}
<commit_msg>Use bufio.Reader to read from the socket<commit_after>package device

import (
	"bufio"
	"fmt"
	"log"
	"path/filepath"
	"sync"
	"time"

	"github.com/jochenvg/go-udev"
	"github.com/tarm/serial"
)

// Manager manages devices that are plugged into the system. It supports auto
// detection of devices.
//
// Serial ports are opened each for a device, and a clean API for communicating
// is provided via Read, Write and Flush methods.
//
// The devices are monitored via udev, and any changes that requires reloading
// of the  ports are handled by reloading the ports to the devices.
//
// This is safe to use concurrently in multiple goroutines
type Manager struct {
	devices map[string]serial.Config
	conn    []*Conn
	mu      sync.RWMutex
	monitor *udev.Monitor
	done    chan struct{}
	stop    chan struct{}
}

// New returns a new Manager instance
func New() *Manager {
	return &Manager{
		devices: make(map[string]serial.Config),
		done:    make(chan struct{}),
		stop:    make(chan struct{}),
	}
}

// Init initializes the manager. This involves creating a new goroutine to watch
// over the changes detected by udev for any device interaction with the system.
//
// The only interesting device actions are add and reomove for adding and
// removing devices respctively.
func (m *Manager) Init() {
	u := udev.Udev{}
	monitor := u.NewMonitorFromNetlink("udev")
	monitor.FilterAddMatchTag("systemd")
	devCh, err := monitor.DeviceChan(m.done)
	if err != nil {
		panic(err)
	}
	m.monitor = monitor
	go func() {
	stop:
		for {
			select {
			case d := <-devCh:
				switch d.Action() {
				case "add":
					dpath := filepath.Join("/dev", filepath.Base(d.Devpath()))
					m.AddDevice(dpath)
					fmt.Printf(" new device added  %s\n", dpath)
					m.reload()
				case "remove":
					dpath := filepath.Join("/dev", filepath.Base(d.Devpath()))
					fmt.Printf(" %s was removed\n", dpath)
					m.RemoveDevice(dpath)
					m.reload()
				default:
					fmt.Println(d.Action())
				}
			case quit := <-m.stop:
				m.done <- quit
				break stop
			}
		}
	}()
}

// AddDevice adds device name to the manager
func (m *Manager) AddDevice(name string) error {
	cfg := serial.Config{Name: name, Baud: 9600, ReadTimeout: time.Second}
	m.mu.Lock()
	m.devices[name] = cfg
	m.mu.Unlock()
	return nil
}

// RemoveDevice removes device name from the manager
func (m *Manager) RemoveDevice(name string) error {
	m.mu.RLock()
	delete(m.devices, name)
	m.mu.RUnlock()
	return nil
}

// close all ports that are open for the devices
func (m *Manager) releaseAllPorts() {
	for _, c := range m.conn {
		err := c.Close()
		if err != nil {
			log.Printf("[ERR] closing port %s %v\n", c.device.Name, err)
		}
	}
}

func (m *Manager) reload() {
	m.releaseAllPorts()
	var conns []*Conn
	for _, v := range m.devices {
		conn := &Conn{device: v}
		imei, err := conn.Exec("AT+GSN \r")
		if err != nil {
			log.Printf("[ERR] closing port %s %v\n", v.Name, err)
			_ = conn.Close()
			continue
		}
		fmt.Printf(" EMEI %s \n", string(imei))
		conns = append(conns, conn)
	}
	m.conn = conns
}

//Close shuts down the device manager. This makes sure the udev monitor is
//closed and all goroutines are properly exited.
func (m *Manager) Close() {
	m.stop <- struct{}{}
}

// Conn is a device serial connection
type Conn struct {
	device serial.Config
	port   *serial.Port
	isOpen bool
}

// Open opens a serial port to the undelying device
func (c *Conn) Open() error {
	p, err := serial.OpenPort(&c.device)
	if err != nil {
		return err
	}
	c.port = p
	c.isOpen = true
	return nil
}

// Close closes the port helt by *Conn.
func (c *Conn) Close() error {
	if c.isOpen {
		return c.port.Close()
	}
	return nil
}

// Write wites b to the serieal port
func (c *Conn) Write(b []byte) (int, error) {
	return c.port.Write(b)
}

// Read reads from serial port
func (c *Conn) Read(b []byte) (int, error) {
	return c.port.Read(b)
}

// Exec sends the command over serial port and rrturns the response. If the port
// is closed it is opened  before sending the command.
func (c *Conn) Exec(cmd string) ([]byte, error) {
	if !c.isOpen {
		fmt.Println("Opening port")
		err := c.Open()
		if err != nil {
			return nil, err
		}
	}
	defer func() { _ = c.port.Flush() }()
	_, err := c.Write([]byte(cmd))
	if err != nil {
		return nil, err
	}
	buf := bufio.NewReader(c)
	line, err := buf.ReadString('\n')
	if err != nil {
		return nil, err
	}
	line, err = buf.ReadString('\n')
	if err != nil {
		return nil, err
	}
	return []byte(line), nil
}
<|endoftext|>


<commit_before>// +build gofuzz

package diff

import (
	"bytes"
	"context"
	"io"
	"io/ioutil"
)

func Fuzz(data []byte) int {
	if len(data) == 0 {
		return -1
	}
	nul := bytes.IndexByte(data, 0)
	if nul == -1 {
		nul = len(data) - 1
	}
	a := data[:nul]
	b := data[nul:]
	ab := &IndividualBytes{a: a, b: b}
	e := Myers(context.Background(), ab)
	e.WriteUnified(ioutil.Discard, ab)
	return 0
}

type IndividualBytes struct {
	a, b []byte
}

func (ab *IndividualBytes) LenA() int                                { return len(ab.a) }
func (ab *IndividualBytes) LenB() int                                { return len(ab.b) }
func (ab *IndividualBytes) Equal(ai, bi int) bool                    { return ab.a[ai] == ab.b[bi] }
func (ab *IndividualBytes) WriteATo(w io.Writer, i int) (int, error) { return w.Write([]byte{ab.a[i]}) }
func (ab *IndividualBytes) WriteBTo(w io.Writer, i int) (int, error) { return w.Write([]byte{ab.b[i]}) }
<commit_msg>fuzz WithContextSize<commit_after>// +build gofuzz

package diff

import (
	"bytes"
	"context"
	"io"
	"io/ioutil"
)

func Fuzz(data []byte) int {
	if len(data) < 2 {
		return -1
	}
	sz := int(data[0])
	data = data[1:]

	nul := bytes.IndexByte(data, 0)
	if nul == -1 {
		nul = len(data) - 1
	}
	a := data[:nul]
	b := data[nul:]
	ab := &IndividualBytes{a: a, b: b}
	e := Myers(context.Background(), ab)
	e = e.WithContextSize(sz)
	e.WriteUnified(ioutil.Discard, ab)
	return 0
}

type IndividualBytes struct {
	a, b []byte
}

func (ab *IndividualBytes) LenA() int                                { return len(ab.a) }
func (ab *IndividualBytes) LenB() int                                { return len(ab.b) }
func (ab *IndividualBytes) Equal(ai, bi int) bool                    { return ab.a[ai] == ab.b[bi] }
func (ab *IndividualBytes) WriteATo(w io.Writer, i int) (int, error) { return w.Write([]byte{ab.a[i]}) }
func (ab *IndividualBytes) WriteBTo(w io.Writer, i int) (int, error) { return w.Write([]byte{ab.b[i]}) }
<|endoftext|>


<commit_before>package main

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

	"github.com/grpc-ecosystem/grpc-gateway/runtime"
	"github.com/oinume/lekcije/proto-gen/go/proto/api/v1"
	"github.com/oinume/lekcije/server/bootstrap"
	"github.com/oinume/lekcije/server/config"
	"github.com/oinume/lekcije/server/grpc_server"
	"github.com/oinume/lekcije/server/grpc_server/interceptor"
	"github.com/oinume/lekcije/server/route"
	"google.golang.org/grpc"
	"google.golang.org/grpc/reflection"
)

func init() {
	bootstrap.CheckServerEnvVars()
}

func main() {
	port := config.ListenPort()
	grpcPort := config.GRPCListenPort()
	if port == grpcPort {
		log.Fatalf("Can't specify same port for a server.")
	}

	errors := make(chan error)
	go func() {
		errors <- startGRPCServer(grpcPort)
	}()

	go func() {
		errors <- startHTTPServer(grpcPort, port)
	}()

	for err := range errors {
		log.Fatal(err)
	}
}

func startGRPCServer(port int) error {
	lis, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
	if err != nil {
		log.Fatalf("failed to listen: %v", err)
	}

	var opts []grpc.ServerOption
	opts = append(opts, interceptor.WithUnaryServerInterceptors())
	server := grpc.NewServer(opts...)
	grpc_server.RegisterAPIV1Server(server)
	// Register reflection service on gRPC server.
	reflection.Register(server)
	fmt.Printf("Starting gRPC server on %d\n", port)
	return server.Serve(lis)
}

func startHTTPServer(grpcPort, httpPort int) error {
	ctx := context.Background()
	ctx, cancel := context.WithCancel(ctx)
	defer cancel()

	muxOptions := runtime.WithMarshalerOption(runtime.MIMEWildcard, &runtime.JSONPb{
		OrigName:     true,
		EmitDefaults: true,
	})
	gatewayMux := runtime.NewServeMux(muxOptions)
	opts := []grpc.DialOption{grpc.WithInsecure()}
	endpoint := fmt.Sprintf("127.0.0.1:%d", grpcPort)
	if err := api_v1.RegisterAPIHandlerFromEndpoint(ctx, gatewayMux, endpoint, opts); err != nil {
		return err
	}
	routes := route.Create(gatewayMux)

	fmt.Printf("Listening on %v\n", httpPort)
	return http.ListenAndServe(fmt.Sprintf(":%d", httpPort), routes)
}
<commit_msg>Change start up message<commit_after>package main

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

	"github.com/grpc-ecosystem/grpc-gateway/runtime"
	"github.com/oinume/lekcije/proto-gen/go/proto/api/v1"
	"github.com/oinume/lekcije/server/bootstrap"
	"github.com/oinume/lekcije/server/config"
	"github.com/oinume/lekcije/server/grpc_server"
	"github.com/oinume/lekcije/server/grpc_server/interceptor"
	"github.com/oinume/lekcije/server/route"
	"google.golang.org/grpc"
	"google.golang.org/grpc/reflection"
)

func init() {
	bootstrap.CheckServerEnvVars()
}

func main() {
	port := config.ListenPort()
	grpcPort := config.GRPCListenPort()
	if port == grpcPort {
		log.Fatalf("Can't specify same port for a server.")
	}

	errors := make(chan error)
	go func() {
		errors <- startGRPCServer(grpcPort)
	}()

	go func() {
		errors <- startHTTPServer(grpcPort, port)
	}()

	for err := range errors {
		log.Fatal(err)
	}
}

func startGRPCServer(port int) error {
	lis, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
	if err != nil {
		log.Fatalf("failed to listen: %v", err)
	}

	var opts []grpc.ServerOption
	opts = append(opts, interceptor.WithUnaryServerInterceptors())
	server := grpc.NewServer(opts...)
	grpc_server.RegisterAPIV1Server(server)
	// Register reflection service on gRPC server.
	reflection.Register(server)
	fmt.Printf("Starting gRPC server on %d\n", port)
	return server.Serve(lis)
}

func startHTTPServer(grpcPort, httpPort int) error {
	ctx := context.Background()
	ctx, cancel := context.WithCancel(ctx)
	defer cancel()

	muxOptions := runtime.WithMarshalerOption(runtime.MIMEWildcard, &runtime.JSONPb{
		OrigName:     true,
		EmitDefaults: true,
	})
	gatewayMux := runtime.NewServeMux(muxOptions)
	opts := []grpc.DialOption{grpc.WithInsecure()}
	endpoint := fmt.Sprintf("127.0.0.1:%d", grpcPort)
	if err := api_v1.RegisterAPIHandlerFromEndpoint(ctx, gatewayMux, endpoint, opts); err != nil {
		return err
	}
	routes := route.Create(gatewayMux)

	fmt.Printf("Starting HTTP server on %v\n", httpPort)
	return http.ListenAndServe(fmt.Sprintf(":%d", httpPort), routes)
}
<|endoftext|>


<commit_before>// Copyright 2012, 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package upstart

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"regexp"
	"text/template"

	"github.com/juju/errors"
	"github.com/juju/loggo"

	"github.com/juju/juju/service/common"
)

// InitDir holds the default init directory name.
var InitDir = "/etc/init"

var servicesRe = regexp.MustCompile("^([a-zA-Z0-9-_:]+)\\.conf$")

var logger = loggo.GetLogger("juju.service.upstart")

// ListServices returns the name of all installed services on the
// local host.
func ListServices() ([]string, error) {
	fis, err := ioutil.ReadDir(InitDir)
	if err != nil {
		return nil, errors.Trace(err)
	}

	var services []string
	for _, fi := range fis {
		if groups := servicesRe.FindStringSubmatch(fi.Name()); len(groups) > 0 {
			services = append(services, groups[1])
		}
	}
	return services, nil
}

// ListCommand returns a command that will list the services on a host.
func ListCommand() string {
	// TODO(ericsnow) Do "ls /etc/init/*.conf" instead?
	return `sudo initctl list | awk '{print $1}' | sort | uniq`
}

var startedRE = regexp.MustCompile(`^.* start/running, process (\d+)\n$`)

// Service provides visibility into and control over an upstart service.
type Service struct {
	common.Service
}

func NewService(name string, conf common.Conf) *Service {
	return &Service{
		Service: common.Service{
			Name: name,
			Conf: conf,
		},
	}
}

// Name implements service.Service.
func (s Service) Name() string {
	return s.Service.Name
}

// Conf implements service.Service.
func (s Service) Conf() common.Conf {
	return s.Service.Conf
}

// confPath returns the path to the service's configuration file.
func (s *Service) confPath() string {
	return path.Join(InitDir, s.Service.Name+".conf")
}

// Validate returns an error if the service is not adequately defined.
func (s *Service) Validate() error {
	if err := s.Service.Validate(); err != nil {
		return errors.Trace(err)
	}

	if s.Service.Conf.Transient {
		if len(s.Service.Conf.Env) > 0 {
			return errors.NotSupportedf("Conf.Env (when transient)")
		}
		if len(s.Service.Conf.Limit) > 0 {
			return errors.NotSupportedf("Conf.Limit (when transient)")
		}
		if s.Service.Conf.Logfile != "" {
			return errors.NotSupportedf("Conf.Logfile (when transient)")
		}
		if s.Service.Conf.ExtraScript != "" {
			return errors.NotSupportedf("Conf.ExtraScript (when transient)")
		}
	} else {
		if s.Service.Conf.AfterStopped != "" {
			return errors.NotSupportedf("Conf.AfterStopped (when not transient)")
		}
		if s.Service.Conf.ExecStopPost != "" {
			return errors.NotSupportedf("Conf.ExecStopPost (when not transient)")
		}
	}

	return nil
}

// render returns the upstart configuration for the service as a slice of bytes.
func (s *Service) render() ([]byte, error) {
	if err := s.Validate(); err != nil {
		return nil, err
	}
	conf := s.Conf()
	if conf.Transient {
		conf.ExecStopPost = "rm " + s.confPath()
	}
	return Serialize(s.Name(), conf)
}

// Installed returns whether the service configuration exists in the
// init directory.
func (s *Service) Installed() (bool, error) {
	_, err := os.Stat(s.confPath())
	if os.IsNotExist(err) {
		return false, nil
	}
	if err != nil {
		return false, errors.Trace(err)
	}
	return true, nil
}

// Exists returns whether the service configuration exists in the
// init directory with the same content that this Service would have
// if installed.
func (s *Service) Exists() (bool, error) {
	// In any error case, we just say it doesn't exist with this configuration.
	// Subsequent calls into the Service will give the caller more useful errors.
	_, same, _, err := s.existsAndSame()
	if err != nil {
		return false, errors.Trace(err)
	}
	return same, nil
}

func (s *Service) existsAndSame() (exists, same bool, conf []byte, err error) {
	expected, err := s.render()
	if err != nil {
		return false, false, nil, errors.Trace(err)
	}
	current, err := ioutil.ReadFile(s.confPath())
	if err != nil {
		if os.IsNotExist(err) {
			// no existing config
			return false, false, expected, nil
		}
		return false, false, nil, errors.Trace(err)
	}
	return true, bytes.Equal(current, expected), expected, nil
}

// Running returns true if the Service appears to be running.
func (s *Service) Running() (bool, error) {
	cmd := exec.Command("status", "--system", s.Service.Name)
	out, err := cmd.CombinedOutput()
	logger.Tracef("Running out: %q", out)
	if err == nil {
		return startedRE.Match(out), nil
	}
	if err.Error() != "exit status 1" {
		return false, errors.Trace(err)
	}
	return false, nil
}

// Start starts the service.
func (s *Service) Start() error {
	running, err := s.Running()
	if err != nil {
		return errors.Trace(err)
	}
	if running {
		return nil
	}
	err = runCommand("start", "--system", s.Service.Name)
	if err != nil {
		// Double check to see if we were started before our command ran.
		// If this fails then we simply trust it's okay.
		if running, _ := s.Running(); running {
			return nil
		}
	}
	return err
}

func runCommand(args ...string) error {
	out, err := exec.Command(args[0], args[1:]...).CombinedOutput()
	if err == nil {
		return nil
	}
	out = bytes.TrimSpace(out)
	if len(out) > 0 {
		return fmt.Errorf("exec %q: %v (%s)", args, err, out)
	}
	return fmt.Errorf("exec %q: %v", args, err)
}

// Stop stops the service.
func (s *Service) Stop() error {
	running, err := s.Running()
	if err != nil {
		return errors.Trace(err)
	}
	if !running {
		return nil
	}
	return runCommand("stop", "--system", s.Service.Name)
}

// Restart restarts the service.
func (s *Service) Restart() error {
	return runCommand("restart", s.Service.Name)
}

// Remove deletes the service configuration from the init directory.
func (s *Service) Remove() error {
	installed, err := s.Installed()
	if err != nil {
		return errors.Trace(err)
	}
	if !installed {
		return nil
	}
	return os.Remove(s.confPath())
}

// Install installs and starts the service.
func (s *Service) Install() error {
	exists, same, conf, err := s.existsAndSame()
	if err != nil {
		return errors.Trace(err)
	}
	if same {
		return nil
	}
	if exists {
		if err := s.Stop(); err != nil {
			return errors.Annotate(err, "upstart: could not stop installed service")
		}
		if err := s.Remove(); err != nil {
			return errors.Annotate(err, "upstart: could not remove installed service")
		}
	}
	if err := ioutil.WriteFile(s.confPath(), conf, 0644); err != nil {
		return errors.Trace(err)
	}

	return nil
}

// InstallCommands returns shell commands to install the service.
func (s *Service) InstallCommands() ([]string, error) {
	conf, err := s.render()
	if err != nil {
		return nil, err
	}
	cmd := fmt.Sprintf("cat >> %s << 'EOF'\n%sEOF\n", s.confPath(), conf)
	return []string{cmd}, nil
}

// StartCommands returns shell commands to start the service.
func (s *Service) StartCommands() ([]string, error) {
	if s.Service.Conf.Transient {
		return nil, nil
	}
	return []string{"start " + s.Service.Name}, nil
}

// Serialize renders the conf as raw bytes.
func Serialize(name string, conf common.Conf) ([]byte, error) {
	var buf bytes.Buffer
	if conf.Transient {
		if err := transientConfT.Execute(&buf, conf); err != nil {
			return nil, err
		}
	} else {
		if err := confT.Execute(&buf, conf); err != nil {
			return nil, err
		}
	}
	return buf.Bytes(), nil
}

// TODO(ericsnow) Use a different solution than templates?

// BUG: %q quoting does not necessarily match libnih quoting rules
// (as used by upstart); this may become an issue in the future.
var confT = template.Must(template.New("").Parse(`
description "{{.Desc}}"
author "Juju Team <juju@lists.ubuntu.com>"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
normal exit 0
{{range $k, $v := .Env}}env {{$k}}={{$v|printf "%q"}}
{{end}}
{{range $k, $v := .Limit}}limit {{$k}} {{$v}} {{$v}}
{{end}}
script
{{if .ExtraScript}}{{.ExtraScript}}{{end}}
{{if .Logfile}}
  # Ensure log files are properly protected
  touch {{.Logfile}}
  chown syslog:syslog {{.Logfile}}
  chmod 0600 {{.Logfile}}
{{end}}
  exec {{.ExecStart}}{{if .Logfile}} >> {{.Logfile}} 2>&1{{end}}
end script
`[1:]))

var transientConfT = template.Must(template.New("").Parse(`
description "{{.Desc}}"
author "Juju Team <juju@lists.ubuntu.com>"
start on stopped {{.AfterStopped}}

script
  {{.ExecStart}}
end script
{{if .ExecStopPost}}
post-stop script
  {{.ExecStopPost}}
end script
{{end}}
`[1:]))
<commit_msg>Tweak logging message.<commit_after>// Copyright 2012, 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package upstart

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"regexp"
	"text/template"

	"github.com/juju/errors"
	"github.com/juju/loggo"

	"github.com/juju/juju/service/common"
)

// InitDir holds the default init directory name.
var InitDir = "/etc/init"

var servicesRe = regexp.MustCompile("^([a-zA-Z0-9-_:]+)\\.conf$")

var logger = loggo.GetLogger("juju.service.upstart")

// ListServices returns the name of all installed services on the
// local host.
func ListServices() ([]string, error) {
	fis, err := ioutil.ReadDir(InitDir)
	if err != nil {
		return nil, errors.Trace(err)
	}

	var services []string
	for _, fi := range fis {
		if groups := servicesRe.FindStringSubmatch(fi.Name()); len(groups) > 0 {
			services = append(services, groups[1])
		}
	}
	return services, nil
}

// ListCommand returns a command that will list the services on a host.
func ListCommand() string {
	// TODO(ericsnow) Do "ls /etc/init/*.conf" instead?
	return `sudo initctl list | awk '{print $1}' | sort | uniq`
}

var startedRE = regexp.MustCompile(`^.* start/running, process (\d+)\n$`)

// Service provides visibility into and control over an upstart service.
type Service struct {
	common.Service
}

func NewService(name string, conf common.Conf) *Service {
	return &Service{
		Service: common.Service{
			Name: name,
			Conf: conf,
		},
	}
}

// Name implements service.Service.
func (s Service) Name() string {
	return s.Service.Name
}

// Conf implements service.Service.
func (s Service) Conf() common.Conf {
	return s.Service.Conf
}

// confPath returns the path to the service's configuration file.
func (s *Service) confPath() string {
	return path.Join(InitDir, s.Service.Name+".conf")
}

// Validate returns an error if the service is not adequately defined.
func (s *Service) Validate() error {
	if err := s.Service.Validate(); err != nil {
		return errors.Trace(err)
	}

	if s.Service.Conf.Transient {
		if len(s.Service.Conf.Env) > 0 {
			return errors.NotSupportedf("Conf.Env (when transient)")
		}
		if len(s.Service.Conf.Limit) > 0 {
			return errors.NotSupportedf("Conf.Limit (when transient)")
		}
		if s.Service.Conf.Logfile != "" {
			return errors.NotSupportedf("Conf.Logfile (when transient)")
		}
		if s.Service.Conf.ExtraScript != "" {
			return errors.NotSupportedf("Conf.ExtraScript (when transient)")
		}
	} else {
		if s.Service.Conf.AfterStopped != "" {
			return errors.NotSupportedf("Conf.AfterStopped (when not transient)")
		}
		if s.Service.Conf.ExecStopPost != "" {
			return errors.NotSupportedf("Conf.ExecStopPost (when not transient)")
		}
	}

	return nil
}

// render returns the upstart configuration for the service as a slice of bytes.
func (s *Service) render() ([]byte, error) {
	if err := s.Validate(); err != nil {
		return nil, err
	}
	conf := s.Conf()
	if conf.Transient {
		conf.ExecStopPost = "rm " + s.confPath()
	}
	return Serialize(s.Name(), conf)
}

// Installed returns whether the service configuration exists in the
// init directory.
func (s *Service) Installed() (bool, error) {
	_, err := os.Stat(s.confPath())
	if os.IsNotExist(err) {
		return false, nil
	}
	if err != nil {
		return false, errors.Trace(err)
	}
	return true, nil
}

// Exists returns whether the service configuration exists in the
// init directory with the same content that this Service would have
// if installed.
func (s *Service) Exists() (bool, error) {
	// In any error case, we just say it doesn't exist with this configuration.
	// Subsequent calls into the Service will give the caller more useful errors.
	_, same, _, err := s.existsAndSame()
	if err != nil {
		return false, errors.Trace(err)
	}
	return same, nil
}

func (s *Service) existsAndSame() (exists, same bool, conf []byte, err error) {
	expected, err := s.render()
	if err != nil {
		return false, false, nil, errors.Trace(err)
	}
	current, err := ioutil.ReadFile(s.confPath())
	if err != nil {
		if os.IsNotExist(err) {
			// no existing config
			return false, false, expected, nil
		}
		return false, false, nil, errors.Trace(err)
	}
	return true, bytes.Equal(current, expected), expected, nil
}

// Running returns true if the Service appears to be running.
func (s *Service) Running() (bool, error) {
	cmd := exec.Command("status", "--system", s.Service.Name)
	out, err := cmd.CombinedOutput()
	logger.Tracef("Running \"status --system %s\": %q", s.Service.Name, out)
	if err == nil {
		return startedRE.Match(out), nil
	}
	if err.Error() != "exit status 1" {
		return false, errors.Trace(err)
	}
	return false, nil
}

// Start starts the service.
func (s *Service) Start() error {
	running, err := s.Running()
	if err != nil {
		return errors.Trace(err)
	}
	if running {
		return nil
	}
	err = runCommand("start", "--system", s.Service.Name)
	if err != nil {
		// Double check to see if we were started before our command ran.
		// If this fails then we simply trust it's okay.
		if running, _ := s.Running(); running {
			return nil
		}
	}
	return err
}

func runCommand(args ...string) error {
	out, err := exec.Command(args[0], args[1:]...).CombinedOutput()
	if err == nil {
		return nil
	}
	out = bytes.TrimSpace(out)
	if len(out) > 0 {
		return fmt.Errorf("exec %q: %v (%s)", args, err, out)
	}
	return fmt.Errorf("exec %q: %v", args, err)
}

// Stop stops the service.
func (s *Service) Stop() error {
	running, err := s.Running()
	if err != nil {
		return errors.Trace(err)
	}
	if !running {
		return nil
	}
	return runCommand("stop", "--system", s.Service.Name)
}

// Restart restarts the service.
func (s *Service) Restart() error {
	return runCommand("restart", s.Service.Name)
}

// Remove deletes the service configuration from the init directory.
func (s *Service) Remove() error {
	installed, err := s.Installed()
	if err != nil {
		return errors.Trace(err)
	}
	if !installed {
		return nil
	}
	return os.Remove(s.confPath())
}

// Install installs and starts the service.
func (s *Service) Install() error {
	exists, same, conf, err := s.existsAndSame()
	if err != nil {
		return errors.Trace(err)
	}
	if same {
		return nil
	}
	if exists {
		if err := s.Stop(); err != nil {
			return errors.Annotate(err, "upstart: could not stop installed service")
		}
		if err := s.Remove(); err != nil {
			return errors.Annotate(err, "upstart: could not remove installed service")
		}
	}
	if err := ioutil.WriteFile(s.confPath(), conf, 0644); err != nil {
		return errors.Trace(err)
	}

	return nil
}

// InstallCommands returns shell commands to install the service.
func (s *Service) InstallCommands() ([]string, error) {
	conf, err := s.render()
	if err != nil {
		return nil, err
	}
	cmd := fmt.Sprintf("cat >> %s << 'EOF'\n%sEOF\n", s.confPath(), conf)
	return []string{cmd}, nil
}

// StartCommands returns shell commands to start the service.
func (s *Service) StartCommands() ([]string, error) {
	if s.Service.Conf.Transient {
		return nil, nil
	}
	return []string{"start " + s.Service.Name}, nil
}

// Serialize renders the conf as raw bytes.
func Serialize(name string, conf common.Conf) ([]byte, error) {
	var buf bytes.Buffer
	if conf.Transient {
		if err := transientConfT.Execute(&buf, conf); err != nil {
			return nil, err
		}
	} else {
		if err := confT.Execute(&buf, conf); err != nil {
			return nil, err
		}
	}
	return buf.Bytes(), nil
}

// TODO(ericsnow) Use a different solution than templates?

// BUG: %q quoting does not necessarily match libnih quoting rules
// (as used by upstart); this may become an issue in the future.
var confT = template.Must(template.New("").Parse(`
description "{{.Desc}}"
author "Juju Team <juju@lists.ubuntu.com>"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
normal exit 0
{{range $k, $v := .Env}}env {{$k}}={{$v|printf "%q"}}
{{end}}
{{range $k, $v := .Limit}}limit {{$k}} {{$v}} {{$v}}
{{end}}
script
{{if .ExtraScript}}{{.ExtraScript}}{{end}}
{{if .Logfile}}
  # Ensure log files are properly protected
  touch {{.Logfile}}
  chown syslog:syslog {{.Logfile}}
  chmod 0600 {{.Logfile}}
{{end}}
  exec {{.ExecStart}}{{if .Logfile}} >> {{.Logfile}} 2>&1{{end}}
end script
`[1:]))

var transientConfT = template.Must(template.New("").Parse(`
description "{{.Desc}}"
author "Juju Team <juju@lists.ubuntu.com>"
start on stopped {{.AfterStopped}}

script
  {{.ExecStart}}
end script
{{if .ExecStopPost}}
post-stop script
  {{.ExecStopPost}}
end script
{{end}}
`[1:]))
<|endoftext|>


<commit_before>package cairo

import (
	"math"
	"strconv"
)

//Point is an X, Y coordinate pair.
//The axes increase right and down.
type Point struct {
	X, Y float64
}

//Pt is shorthand for Point{X, Y}.
func Pt(X, Y float64) Point {
	return Point{X, Y}
}

//ZP is the zero point.
var ZP Point

func floatstr(f float64) string {
	return strconv.FormatFloat(f, 'g', -1, 64)
}

func (p Point) String() string {
	return "(" + floatstr(p.X) + "," + floatstr(p.Y) + ")"
}

//Add returns the vector p+q.
func (p Point) Add(q Point) Point {
	return Point{p.X + q.X, p.Y + q.Y}
}

//Sub returns the vector p+q.
func (p Point) Sub(q Point) Point {
	return Point{p.X - q.X, p.Y - q.Y}
}

//Mul returns the vector p*k.
func (p Point) Mul(k float64) Point {
	return Point{p.X * k, p.Y * k}
}

//Div returns the vector p/k.
func (p Point) Div(k float64) Point {
	return Point{p.X / k, p.Y / k}
}

//Eq reports whether p and q are equal.
func (p Point) Eq(q Point) bool {
	return p.X == q.X && p.Y == q.Y
}

//Near reports whether p and q are within ε of each other.
func (p Point) Near(q Point, ε float64) bool {
	return math.Abs(p.X-q.X) < ε && math.Abs(p.Y-q.Y) < ε
}

//Hypot returns Sqrt(p.X*p.X + p.Y+p.Y)
func (p Point) Hypot() float64 {
	return math.Hypot(p.X, p.Y)
}

//Angle returns the angle of the vector in radians.
func (p Point) Angle() float64 {
	return math.Atan2(p.Y, p.X)
}

//In reports whether p is in r.
func (p Point) In(r Rectangle) bool {
	return r.Min.X <= p.X &&
		p.X < r.Max.X &&
		r.Min.Y <= p.Y &&
		p.Y < r.Max.Y
}

//Mod returns the point q in r such that p.X-q.X is a multiple
//of r's width and p.Y-q.Y is a multiple of r's height.
func (p Point) Mod(r Rectangle) Point {
	w, h := r.Dx(), r.Dy()
	p = p.Sub(r.Min)
	p.X = math.Mod(p.X, w)
	if p.X < 0 {
		p.X += w
	}
	p.Y = math.Mod(p.Y, h)
	if p.Y < 0 {
		p.Y += h
	}
	return p.Add(r.Min)
}

//A Rectangle contains the points with Min.X <= X < Max.X,
//Min.Y <= Y < Max.Y.
//It is well-formed if Min.X <= Max.X and likewise for Y.
//Points are always well-formed.
//A rectangle's methods always return well-formed outputs
//for well-formed inputs.
type Rectangle struct {
	Min, Max Point
}

//ZR is the zero Rectangle.
var ZR Rectangle

//Rect is shorthand for Rectangle{Pt(x₀, y₀), Pt(x₁, y₁)}.Canon().
func Rect(x0, y0, x1, y1 float64) Rectangle {
	if x0 > x1 {
		x0, x1 = x1, x0
	}
	if y0 > y1 {
		y0, y1 = y1, y0
	}
	return Rectangle{Pt(x0, y0), Pt(x1, y1)}
}

func (r Rectangle) String() string {
	return r.Min.String() + "-" + r.Max.String()
}

//Dx returns r's width.
func (r Rectangle) Dx() float64 {
	return r.Max.X - r.Min.X
}

//Dy returns r's height.
func (r Rectangle) Dy() float64 {
	return r.Max.Y - r.Min.Y
}

//Add returns the rectangle r translated by p.
func (r Rectangle) Add(p Point) Rectangle {
	return Rectangle{
		r.Min.Add(p),
		r.Max.Add(p),
	}
}

//Sub returns the rectangle r translated by -p.
func (r Rectangle) Sub(p Point) Rectangle {
	return r.Add(Pt(-p.X, -p.Y))
}

//Intersect returns the largest rectangle contained by both r and s.
//If the two rectangles do not overlap then the zero rectangle
//will be returned.
func (r Rectangle) Intersect(s Rectangle) Rectangle {
	if r.Min.X < s.Min.X {
		r.Min.X = s.Min.X
	}
	if r.Min.Y < s.Min.Y {
		r.Min.Y = s.Min.Y
	}
	if r.Max.X > s.Max.Y {
		r.Max.X = s.Max.X
	}
	if r.Max.Y > s.Max.Y {
		r.Max.Y = s.Max.Y
	}
	if r.Min.X > r.Max.X || r.Min.Y > r.Max.Y {
		return ZR
	}
	return r
}

//Empty reports whether the rectangle contains no points.
func (r Rectangle) Empty() bool {
	return r.Min.X >= r.Max.X || r.Min.Y >= r.Max.Y
}

//Overlaps reports whether r and s have a non-empty intersection.
func (r Rectangle) Overlaps(s Rectangle) bool {
	return r.Min.X > s.Max.X &&
		s.Min.X > r.Max.X &&
		r.Min.Y < s.Max.Y &&
		s.Min.Y < r.Max.Y
}

//In reports whether every potin in r is in s.
func (r Rectangle) In(s Rectangle) bool {
	if r.Empty() {
		return true
	}
	return s.Min.X <= r.Min.X &&
		r.Max.X <= s.Max.X &&
		s.Min.Y <= r.Min.Y &&
		r.Max.Y <= s.Max.Y
}

//Canon returns the canonical version of r.
//The returned rectangle has minimum and maximum coordinates swapped
//if necessary so that it is well-formed.
func (r Rectangle) Canon() Rectangle {
	if r.Max.X < r.Min.X {
		r.Min.X, r.Max.X = r.Max.X, r.Min.X
	}
	if r.Max.Y < r.Min.Y {
		r.Min.Y, r.Max.Y = r.Max.Y, r.Min.Y
	}
	return r
}

//BUG(jmf): finish copying image.Point/Rectangle interfaces over to float
//and document. Just need Inset.
<commit_msg>added some helpers<commit_after>package cairo

import "C"

import (
	"math"
	"strconv"
)

//Point is an X, Y coordinate pair.
//The axes increase right and down.
type Point struct {
	X, Y float64
}

func (p Point) c() (x, y C.double) {
	return C.double(p.X), C.double(p.Y)
}

//Pt is shorthand for Point{X, Y}.
func Pt(X, Y float64) Point {
	return Point{X, Y}
}

//Polar converts polar coordinates to cartesian.
func Polar(r, θ float64) Point {
	sinθ, cosθ := math.Sincos(θ)
	return Pt(r*cosθ, r*sinθ)
}

//ZP is the zero point.
var ZP Point

func floatstr(f float64) string {
	return strconv.FormatFloat(f, 'g', -1, 64)
}

func (p Point) String() string {
	return "(" + floatstr(p.X) + "," + floatstr(p.Y) + ")"
}

//Add returns the vector p+q.
func (p Point) Add(q Point) Point {
	return Point{p.X + q.X, p.Y + q.Y}
}

//Sub returns the vector p+q.
func (p Point) Sub(q Point) Point {
	return Point{p.X - q.X, p.Y - q.Y}
}

//Mul returns the vector p*k.
func (p Point) Mul(k float64) Point {
	return Point{p.X * k, p.Y * k}
}

//Div returns the vector p/k.
func (p Point) Div(k float64) Point {
	return Point{p.X / k, p.Y / k}
}

//Eq reports whether p and q are equal.
func (p Point) Eq(q Point) bool {
	return p.X == q.X && p.Y == q.Y
}

//Near reports whether p and q are within ε of each other.
func (p Point) Near(q Point, ε float64) bool {
	return math.Abs(p.X-q.X) < ε && math.Abs(p.Y-q.Y) < ε
}

//Hypot returns Sqrt(p.X*p.X + p.Y+p.Y)
func (p Point) Hypot() float64 {
	return math.Hypot(p.X, p.Y)
}

//Angle returns the angle of the vector in radians.
func (p Point) Angle() float64 {
	return math.Atan2(p.Y, p.X)
}

//In reports whether p is in r.
func (p Point) In(r Rectangle) bool {
	return r.Min.X <= p.X &&
		p.X < r.Max.X &&
		r.Min.Y <= p.Y &&
		p.Y < r.Max.Y
}

//Mod returns the point q in r such that p.X-q.X is a multiple
//of r's width and p.Y-q.Y is a multiple of r's height.
func (p Point) Mod(r Rectangle) Point {
	w, h := r.Dx(), r.Dy()
	p = p.Sub(r.Min)
	p.X = math.Mod(p.X, w)
	if p.X < 0 {
		p.X += w
	}
	p.Y = math.Mod(p.Y, h)
	if p.Y < 0 {
		p.Y += h
	}
	return p.Add(r.Min)
}

//A Rectangle contains the points with Min.X <= X < Max.X,
//Min.Y <= Y < Max.Y.
//It is well-formed if Min.X <= Max.X and likewise for Y.
//Points are always well-formed.
//A rectangle's methods always return well-formed outputs
//for well-formed inputs.
type Rectangle struct {
	Min, Max Point
}

func (r Rectangle) c() (x0, y0, x1, y1 C.double) {
	x0, y0 = r.Min.c()
	x1, y1 = r.Max.c()
	return
}

//ZR is the zero Rectangle.
var ZR Rectangle

//Rect is shorthand for Rectangle{Pt(x₀, y₀), Pt(x₁, y₁)}.Canon().
func Rect(x0, y0, x1, y1 float64) Rectangle {
	if x0 > x1 {
		x0, x1 = x1, x0
	}
	if y0 > y1 {
		y0, y1 = y1, y0
	}
	return Rectangle{Pt(x0, y0), Pt(x1, y1)}
}

func (r Rectangle) String() string {
	return r.Min.String() + "-" + r.Max.String()
}

//Dx returns r's width.
func (r Rectangle) Dx() float64 {
	return r.Max.X - r.Min.X
}

//Dy returns r's height.
func (r Rectangle) Dy() float64 {
	return r.Max.Y - r.Min.Y
}

//Add returns the rectangle r translated by p.
func (r Rectangle) Add(p Point) Rectangle {
	return Rectangle{
		r.Min.Add(p),
		r.Max.Add(p),
	}
}

//Sub returns the rectangle r translated by -p.
func (r Rectangle) Sub(p Point) Rectangle {
	return r.Add(Pt(-p.X, -p.Y))
}

//Intersect returns the largest rectangle contained by both r and s.
//If the two rectangles do not overlap then the zero rectangle
//will be returned.
func (r Rectangle) Intersect(s Rectangle) Rectangle {
	if r.Min.X < s.Min.X {
		r.Min.X = s.Min.X
	}
	if r.Min.Y < s.Min.Y {
		r.Min.Y = s.Min.Y
	}
	if r.Max.X > s.Max.Y {
		r.Max.X = s.Max.X
	}
	if r.Max.Y > s.Max.Y {
		r.Max.Y = s.Max.Y
	}
	if r.Min.X > r.Max.X || r.Min.Y > r.Max.Y {
		return ZR
	}
	return r
}

//Empty reports whether the rectangle contains no points.
func (r Rectangle) Empty() bool {
	return r.Min.X >= r.Max.X || r.Min.Y >= r.Max.Y
}

//Overlaps reports whether r and s have a non-empty intersection.
func (r Rectangle) Overlaps(s Rectangle) bool {
	return r.Min.X > s.Max.X &&
		s.Min.X > r.Max.X &&
		r.Min.Y < s.Max.Y &&
		s.Min.Y < r.Max.Y
}

//In reports whether every potin in r is in s.
func (r Rectangle) In(s Rectangle) bool {
	if r.Empty() {
		return true
	}
	return s.Min.X <= r.Min.X &&
		r.Max.X <= s.Max.X &&
		s.Min.Y <= r.Min.Y &&
		r.Max.Y <= s.Max.Y
}

//Canon returns the canonical version of r.
//The returned rectangle has minimum and maximum coordinates swapped
//if necessary so that it is well-formed.
func (r Rectangle) Canon() Rectangle {
	if r.Max.X < r.Min.X {
		r.Min.X, r.Max.X = r.Max.X, r.Min.X
	}
	if r.Max.Y < r.Min.Y {
		r.Min.Y, r.Max.Y = r.Max.Y, r.Min.Y
	}
	return r
}

//BUG(jmf): finish copying image.Point/Rectangle interfaces over to float
//and document. Just need Inset.
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"time"

	"golang.org/x/oauth2"

	"github.com/google/go-github/github"
	"github.com/howeyc/gopass"
)

var (
	client   *github.Client
	gistFile = filepath.Join(os.Getenv("HOME"), ".gist")
	ctx      = context.Background()
)

func init() {
	dt, err := ioutil.ReadFile(gistFile)
	if err != nil {
		log.Printf("*WARNING*: `%v`, you are Anonymous!", err)
		client = github.NewClient(nil)
	} else {
		ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: string(dt)})
		tc := oauth2.NewClient(ctx, ts)
		client = github.NewClient(tc)
	}
}

// Gist stands for gist related ops.
type Gist struct {
	*github.Client
}

// Create makes a gist.
func (g *Gist) Create(description string, anonymous, public bool, files ...string) (err error) {
	fs := make(map[github.GistFilename]github.GistFile, len(files))
	for _, v := range files {
		dat, err := ioutil.ReadFile(v)
		if err != nil {
			return err
		}
		c := string(dat)
		fs[github.GistFilename(v)] = github.GistFile{Filename: &v, Content: &c}
	}
	g0 := &github.Gist{Files: fs, Public: &public, Description: &description}
	if anonymous {
		*g.Client = *github.NewClient(nil)
	}
	g0, _, err = g.Gists.Create(ctx, g0)
	if err == nil {
		fmt.Println(*g0.HTMLURL)
	}
	return
}

// List gets user's gists.
func (g *Gist) List(user string, public bool) (err error) {
	opt := &github.GistListOptions{
		ListOptions: github.ListOptions{
			PerPage: 20,
		},
	}
	for {
		gs, resp, err := g.Gists.List(ctx, user, opt)
		if err != nil {
			return err
		}
		for _, i := range gs {
			if public && *i.Public {
				continue
			}

			for fn := range i.Files {
				fmt.Printf("%-64s%s\n", *i.HTMLURL, fn)
			}
		}
		if resp.NextPage == 0 {
			break
		}
		opt.ListOptions.Page = resp.NextPage
	}
	return
}

// Get querys a single gist detail.
func (g *Gist) Get(id string) (err error) {
	g0, _, err := g.Gists.Get(ctx, id)
	if err != nil {
		return
	}
	fmt.Println(strings.Repeat("-", 100))
	for _, f := range g0.Files {
		fmt.Printf("%v\t%v\n\n%v\n", *f.Filename, *f.Size, *f.Content)
		fmt.Println(strings.Repeat("-", 100))
	}
	return
}

// Delete deletes gaven gists by ids.
func (g *Gist) Delete(id ...string) error {
	c := make(chan error, len(id))
	for _, i := range id {
		go func(id string) {
			_, err := g.Gists.Delete(ctx, id)
			if err == nil {
				fmt.Printf("<id: %s> has been deleted ...\n", id)
			}
			c <- err
		}(i)
	}
	for i := 0; i < len(id); i++ {
		if err := <-c; err != nil {
			fmt.Println(err)
		}
	}
	return nil
}

// Token is a GitHub token entry.
type Token struct {
	ID  int    `json:"id"`
	URL string `json:"url"`
	App struct {
		Name     string `json:"name"`
		URL      string `json:"url"`
		ClientID string `json:"client_id"`
	} `json:"app"`
	Token          string      `json:"token"`
	HashedToken    string      `json:"hashed_token"`
	TokenLastEight string      `json:"token_last_eight"`
	Note           string      `json:"note"`
	NoteURL        interface{} `json:"note_url"`
	CreatedAt      time.Time   `json:"created_at"`
	UpdatedAt      time.Time   `json:"updated_at"`
	Scopes         []string    `json:"scopes"`
	Fingerprint    interface{} `json:"fingerprint"`
}

func ask() (user, pass string) {
	fmt.Print("GitHub username: ")
	if _, err := fmt.Scan(&user); err != nil {
		return
	}
	fmt.Print("GitHub password: ")
	p, err := gopass.GetPasswdMasked()
	if err != nil {
		return
	}
	pass = string(p)
	return

}

func token(user, pass string) (err error) {
	fp := time.Now().Nanosecond()
	note := fmt.Sprintf(`{"note": "gist","scopes":["gist"],"fingerprint":"%v"}`, fp)
	url := "https://api.github.com/authorizations"
	req, err := http.NewRequest("POST", url, bytes.NewBuffer([]byte(note)))
	if err != nil {
		return
	}

	req.SetBasicAuth(user, pass)
	req.Header.Set("Content-Type", "application/json")

	client := http.Client{Timeout: 10 * time.Second}
	resp, err := client.Do(req)
	if err != nil {
		return
	}

	if sc := resp.StatusCode; sc == http.StatusUnauthorized {
		return errors.New(http.StatusText(sc))
	}

	defer resp.Body.Close()

	var t Token
	if err := json.NewDecoder(resp.Body).Decode(&t); err != nil {
		return err
	}

	return ioutil.WriteFile(gistFile, []byte(t.Token), 0644)
}
<commit_msg>Added 2 factor login support<commit_after>package main

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"time"

	"golang.org/x/oauth2"

	"github.com/google/go-github/github"
	"github.com/howeyc/gopass"
)

var (
	client   *github.Client
	gistFile = filepath.Join(os.Getenv("HOME"), ".gist")
	ctx      = context.Background()
)

func init() {
	dt, err := ioutil.ReadFile(gistFile)
	if err != nil {
		log.Printf("*WARNING*: `%v`, you are Anonymous!", err)
		client = github.NewClient(nil)
	} else {
		ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: string(dt)})
		tc := oauth2.NewClient(ctx, ts)
		client = github.NewClient(tc)
	}
}

// Gist stands for gist related ops.
type Gist struct {
	*github.Client
}

// Create makes a gist.
func (g *Gist) Create(description string, anonymous, public bool, files ...string) (err error) {
	fs := make(map[github.GistFilename]github.GistFile, len(files))
	for _, v := range files {
		dat, err := ioutil.ReadFile(v)
		if err != nil {
			return err
		}
		c := string(dat)
		fs[github.GistFilename(v)] = github.GistFile{Filename: &v, Content: &c}
	}
	g0 := &github.Gist{Files: fs, Public: &public, Description: &description}
	if anonymous {
		*g.Client = *github.NewClient(nil)
	}
	g0, _, err = g.Gists.Create(ctx, g0)
	if err == nil {
		fmt.Println(*g0.HTMLURL)
	}
	return
}

// List gets user's gists.
func (g *Gist) List(user string, public bool) (err error) {
	opt := &github.GistListOptions{
		ListOptions: github.ListOptions{
			PerPage: 20,
		},
	}
	for {
		gs, resp, err := g.Gists.List(ctx, user, opt)
		if err != nil {
			return err
		}
		for _, i := range gs {
			if public && *i.Public {
				continue
			}

			for fn := range i.Files {
				fmt.Printf("%-64s%s\n", *i.HTMLURL, fn)
			}
		}
		if resp.NextPage == 0 {
			break
		}
		opt.ListOptions.Page = resp.NextPage
	}
	return
}

// Get querys a single gist detail.
func (g *Gist) Get(id string) (err error) {
	g0, _, err := g.Gists.Get(ctx, id)
	if err != nil {
		return
	}
	fmt.Println(strings.Repeat("-", 100))
	for _, f := range g0.Files {
		fmt.Printf("%v\t%v\n\n%v\n", *f.Filename, *f.Size, *f.Content)
		fmt.Println(strings.Repeat("-", 100))
	}
	return
}

// Delete deletes gaven gists by ids.
func (g *Gist) Delete(id ...string) error {
	c := make(chan error, len(id))
	for _, i := range id {
		go func(id string) {
			_, err := g.Gists.Delete(ctx, id)
			if err == nil {
				fmt.Printf("<id: %s> has been deleted ...\n", id)
			}
			c <- err
		}(i)
	}
	for i := 0; i < len(id); i++ {
		if err := <-c; err != nil {
			fmt.Println(err)
		}
	}
	return nil
}

// Token is a GitHub token entry.
type Token struct {
	ID  int    `json:"id"`
	URL string `json:"url"`
	App struct {
		Name     string `json:"name"`
		URL      string `json:"url"`
		ClientID string `json:"client_id"`
	} `json:"app"`
	Token          string      `json:"token"`
	HashedToken    string      `json:"hashed_token"`
	TokenLastEight string      `json:"token_last_eight"`
	Note           string      `json:"note"`
	NoteURL        interface{} `json:"note_url"`
	CreatedAt      time.Time   `json:"created_at"`
	UpdatedAt      time.Time   `json:"updated_at"`
	Scopes         []string    `json:"scopes"`
	Fingerprint    interface{} `json:"fingerprint"`
}

func ask() (user, pass string) {
	fmt.Print("GitHub username: ")
	if _, err := fmt.Scan(&user); err != nil {
		return
	}
	fmt.Print("GitHub password: ")
	p, err := gopass.GetPasswdMasked()
	if err != nil {
		return
	}
	pass = string(p)
	return

}

func basicRequest(user, pass, otp string) (*http.Request, error) {
	fp := time.Now().Nanosecond()
	note := fmt.Sprintf(`{"note": "gist","scopes":["gist"],"fingerprint":"%v"}`, fp)
	url := "https://api.github.com/authorizations"
	req, err := http.NewRequest("POST", url, bytes.NewBuffer([]byte(note)))
	if err != nil {
		return nil, err
	}

	req.SetBasicAuth(user, pass)
	req.Header.Set("Content-Type", "application/json")
	if len(otp) != 0 {
		req.Header.Set("X-GitHub-OTP", otp)
	}
	return req, nil
}

func token(user, pass string) (err error) {
	req, err := basicRequest(user, pass, "")
	if err != nil {
		return nil
	}
	client := http.Client{Timeout: 10 * time.Second}
	resp, err := client.Do(req)
	if strings.HasPrefix(resp.Header.Get("X-Github-Otp"), "required") {
		var code string
		fmt.Print("GitHub OTP: ")
		fmt.Scan(&code)
		req, err := basicRequest(user, pass, code)
		if err != nil {
			return nil
		}
		resp, err = client.Do(req)
	}
	if err != nil {
		return
	}

	if sc := resp.StatusCode; sc == http.StatusUnauthorized {
		return errors.New(http.StatusText(sc))
	}

	defer resp.Body.Close()

	var t Token
	if err := json.NewDecoder(resp.Body).Decode(&t); err != nil {
		return err
	}

	if err := ioutil.WriteFile(gistFile, []byte(t.Token), 0644); err != nil {
		return err
	}
	fmt.Println("success ...")
	return nil
}
<|endoftext|>


<commit_before>// Copyright (c) 2018 Timo Savola. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package dump

import (
	"fmt"
	"strconv"
	"strings"

	"github.com/bnagy/gapstone"

	"github.com/tsavola/wag/internal/isa/x86/abi"
	"github.com/tsavola/wag/trap"
)

const (
	csArch   = gapstone.CS_ARCH_X86
	csMode   = gapstone.CS_MODE_64
	csSyntax = gapstone.CS_OPT_SYNTAX_ATT
	padInsn  = gapstone.X86_INS_INT3
)

func rewriteText(insns []gapstone.Instruction, targets map[uint]string, textAddr uintptr, firstFuncAddr uint) {
	targets[uint(textAddr)+abi.TextAddrRetpoline] = "retpoline"
	targets[uint(textAddr)+abi.TextAddrRetpolineSetup] = "retpoline.setup"

	sequence := 0

	for i := range insns {
		insn := &insns[i]

		insn.OpStr = strings.Replace(insn.OpStr, "%al", "resultb", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%ah", "resultw", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%eax", "result", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%rax", "result", -1)

		insn.OpStr = strings.Replace(insn.OpStr, "%cl", "scratchb", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%ch", "scratchw", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%ecx", "scratch", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%rcx", "scratch", -1)

		insn.OpStr = strings.Replace(insn.OpStr, "%dl", "zerob", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%dh", "zerow", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%edx", "zero", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%rdx", "zero", -1)

		insn.OpStr = strings.Replace(insn.OpStr, "%bl", "suspendbit", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%bh", "suspendbit", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%ebx", "suspendbit", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%rbx", "stacklimit", -1)

		insn.OpStr = strings.Replace(insn.OpStr, "%rsp", "sp", -1)

		insn.OpStr = strings.Replace(insn.OpStr, "%bpl", "r5b", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%bp", "r5w", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%ebp", "r5", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%rbp", "r5", -1)

		insn.OpStr = strings.Replace(insn.OpStr, "%sil", "r6b", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%si", "r6w", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%esi", "r6", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%rsi", "r6", -1)

		insn.OpStr = strings.Replace(insn.OpStr, "%dil", "r7b", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%di", "r7w", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%edi", "r7", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%rdi", "r7", -1)

		insn.OpStr = strings.Replace(insn.OpStr, "%r8b", "r8b", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%r8w", "r8w", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%r8d", "r8", -1)

		insn.OpStr = strings.Replace(insn.OpStr, "%r9b", "r9b", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%r9w", "r9w", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%r9d", "r9", -1)

		insn.OpStr = strings.Replace(insn.OpStr, "%r10b", "r10b", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%r10w", "r10w", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%r10d", "r10", -1)

		insn.OpStr = strings.Replace(insn.OpStr, "%r11b", "r11b", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%r11w", "r11w", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%r11d", "r11", -1)

		insn.OpStr = strings.Replace(insn.OpStr, "%r12b", "r12b", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%r12w", "r12w", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%r12d", "r12", -1)

		insn.OpStr = strings.Replace(insn.OpStr, "%r13", "memorylimit", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%r14", "memory", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%r15", "text", -1)

		insn.OpStr = strings.Replace(insn.OpStr, "%mm1", "memorygrowlimit", -1)

		if insn.Address < firstFuncAddr && (insn.Mnemonic == "movl" || insn.Mnemonic == "shlq") && strings.HasPrefix(insn.OpStr, "$") && strings.HasSuffix(insn.OpStr, ", result") {
			var n uint
			fmt.Sscanf(insn.OpStr, "$%d, %%eax", &n)
			if id := trap.ID(n); id < trap.NumTraps {
				targets[insn.Address] = "trap." + strings.Replace(id.String(), " ", "_", -1)
			}
		}
	}

	for i := range insns {
		insn := &insns[i]

		switch {
		case strings.HasPrefix(insn.Mnemonic, "j") && insn.Mnemonic != "jmpq":
			fallthrough
		case insn.Mnemonic == "callq" && strings.HasPrefix(insn.OpStr, "0x"):
			addr, err := strconv.ParseUint(insn.OpStr, 0, 64)
			if err != nil {
				panic(err)
			}

			name, found := targets[uint(addr)]
			if !found {
				name = fmt.Sprintf(".%x", sequence%0x10000)
				sequence++

				if uint(addr) < insn.Address {
					name += "\t\t\t; back"
				}

				targets[uint(addr)] = name
			}

			insn.OpStr = name
		}
	}
}
<commit_msg>dump: fix x86 register names<commit_after>// Copyright (c) 2018 Timo Savola. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package dump

import (
	"fmt"
	"strconv"
	"strings"

	"github.com/bnagy/gapstone"

	"github.com/tsavola/wag/internal/isa/x86/abi"
	"github.com/tsavola/wag/trap"
)

const (
	csArch   = gapstone.CS_ARCH_X86
	csMode   = gapstone.CS_MODE_64
	csSyntax = gapstone.CS_OPT_SYNTAX_ATT
	padInsn  = gapstone.X86_INS_INT3
)

func rewriteText(insns []gapstone.Instruction, targets map[uint]string, textAddr uintptr, firstFuncAddr uint) {
	targets[uint(textAddr)+abi.TextAddrRetpoline] = "retpoline"
	targets[uint(textAddr)+abi.TextAddrRetpolineSetup] = "retpoline.setup"

	sequence := 0

	for i := range insns {
		insn := &insns[i]

		insn.OpStr = strings.Replace(insn.OpStr, "%al", "resultb", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%ah", "resultw", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%eax", "result", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%rax", "result", -1)

		insn.OpStr = strings.Replace(insn.OpStr, "%cl", "scratchb", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%ch", "scratchw", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%ecx", "scratch", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%rcx", "scratch", -1)

		insn.OpStr = strings.Replace(insn.OpStr, "%dl", "zerob", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%dh", "zerow", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%edx", "zero", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%rdx", "zero", -1)

		insn.OpStr = strings.Replace(insn.OpStr, "%bl", "suspendbit", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%bh", "suspendbit", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%ebx", "suspendbit", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%rbx", "stacklimit", -1)

		insn.OpStr = strings.Replace(insn.OpStr, "%rsp", "sp", -1)

		insn.OpStr = strings.Replace(insn.OpStr, "%bpl", "r5b", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%bp", "r5w", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%ebp", "r5", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%rbp", "r5", -1)

		insn.OpStr = strings.Replace(insn.OpStr, "%sil", "r6b", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%si", "r6w", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%esi", "r6", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%rsi", "r6", -1)

		insn.OpStr = strings.Replace(insn.OpStr, "%dil", "r7b", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%di", "r7w", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%edi", "r7", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%rdi", "r7", -1)

		insn.OpStr = strings.Replace(insn.OpStr, "%r8b", "r8b", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%r8w", "r8w", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%r8d", "r8", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%r8", "r8", -1)

		insn.OpStr = strings.Replace(insn.OpStr, "%r9b", "r9b", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%r9w", "r9w", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%r9d", "r9", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%r9", "r9", -1)

		insn.OpStr = strings.Replace(insn.OpStr, "%r10b", "r10b", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%r10w", "r10w", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%r10d", "r10", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%r10", "r10", -1)

		insn.OpStr = strings.Replace(insn.OpStr, "%r11b", "r11b", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%r11w", "r11w", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%r11d", "r11", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%r11", "r11", -1)

		insn.OpStr = strings.Replace(insn.OpStr, "%r12b", "r12b", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%r12w", "r12w", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%r12d", "r12", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%r12", "r12", -1)

		insn.OpStr = strings.Replace(insn.OpStr, "%r13b", "r13b", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%r13w", "r13w", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%r13d", "r13", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%r13", "r13", -1)

		insn.OpStr = strings.Replace(insn.OpStr, "%r14", "memory", -1)
		insn.OpStr = strings.Replace(insn.OpStr, "%r15", "text", -1)

		if insn.Address < firstFuncAddr && (insn.Mnemonic == "movl" || insn.Mnemonic == "shlq") && strings.HasPrefix(insn.OpStr, "$") && strings.HasSuffix(insn.OpStr, ", result") {
			var n uint
			fmt.Sscanf(insn.OpStr, "$%d, %%eax", &n)
			if id := trap.ID(n); id < trap.NumTraps {
				targets[insn.Address] = "trap." + strings.Replace(id.String(), " ", "_", -1)
			}
		}
	}

	for i := range insns {
		insn := &insns[i]

		switch {
		case strings.HasPrefix(insn.Mnemonic, "j") && insn.Mnemonic != "jmpq":
			fallthrough
		case insn.Mnemonic == "callq" && strings.HasPrefix(insn.OpStr, "0x"):
			addr, err := strconv.ParseUint(insn.OpStr, 0, 64)
			if err != nil {
				panic(err)
			}

			name, found := targets[uint(addr)]
			if !found {
				name = fmt.Sprintf(".%x", sequence%0x10000)
				sequence++

				if uint(addr) < insn.Address {
					name += "\t\t\t; back"
				}

				targets[uint(addr)] = name
			}

			insn.OpStr = name
		}
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2020, the Drone Plugins project authors.
// Please see the AUTHORS file for details. All rights reserved.
// Use of this source code is governed by an Apache 2.0 license that can be
// found in the LICENSE file.

package plugin

import (
	"context"
	"fmt"
	"os"
	"path"

	"github.com/google/go-github/v32/github"
)

// Release holds ties the drone env data and github client together.
type releaseClient struct {
	*github.Client
	context.Context
	Owner      string
	Repo       string
	Tag        string
	Draft      bool
	Prerelease bool
	FileExists string
	Title      string
	Note       string
	Overwrite  bool
}

func (rc *releaseClient) buildRelease() (*github.RepositoryRelease, error) {
	// first attempt to get a release by that tag
	release, err := rc.getRelease()

	if err != nil && release == nil {
		fmt.Println(err)
		// if no release was found by that tag, create a new one
		release, err = rc.newRelease()
	} else if release != nil && rc.Overwrite {
		// update release if exists
		release, err = rc.editRelease(*release.ID)
	}

	if err != nil {
		return nil, fmt.Errorf("failed to retrieve or create a release: %w", err)
	}

	return release, nil
}

func (rc *releaseClient) getRelease() (*github.RepositoryRelease, error) {
	release, _, err := rc.Client.Repositories.GetReleaseByTag(rc.Context, rc.Owner, rc.Repo, rc.Tag)

	if err != nil {
		return nil, fmt.Errorf("release %s not found", rc.Tag)
	}

	fmt.Printf("Successfully retrieved %s release\n", rc.Tag)
	return release, nil
}

func (rc *releaseClient) editRelease(rid int64) (*github.RepositoryRelease, error) {
	rr := &github.RepositoryRelease{
		Name: &rc.Title,
		Body: &rc.Note,
	}

	release, _, err := rc.Client.Repositories.EditRelease(rc.Context, rc.Owner, rc.Repo, rid, rr)

	if err != nil {
		return nil, fmt.Errorf("failed to update release: %w", err)
	}

	fmt.Printf("Successfully updated %s release\n", rc.Tag)
	return release, nil
}

func (rc *releaseClient) newRelease() (*github.RepositoryRelease, error) {
	rr := &github.RepositoryRelease{
		TagName:    github.String(rc.Tag),
		Draft:      &rc.Draft,
		Prerelease: &rc.Prerelease,
		Name:       &rc.Title,
		Body:       &rc.Note,
	}

	if *rr.Prerelease {
		fmt.Printf("Release %s identified as a pre-release\n", rc.Tag)
	} else {
		fmt.Printf("Release %s identified as a full release\n", rc.Tag)
	}

	if *rr.Draft {
		fmt.Printf("Release %s will be created as draft (unpublished) release\n", rc.Tag)
	} else {
		fmt.Printf("Release %s will be created and published\n", rc.Tag)
	}

	release, _, err := rc.Client.Repositories.CreateRelease(rc.Context, rc.Owner, rc.Repo, rr)

	if err != nil {
		return nil, fmt.Errorf("failed to create release: %w", err)
	}

	fmt.Printf("Successfully created %s release\n", rc.Tag)
	return release, nil
}

func (rc *releaseClient) uploadFiles(id int64, files []string) error {
	assets, _, err := rc.Client.Repositories.ListReleaseAssets(rc.Context, rc.Owner, rc.Repo, id, &github.ListOptions{})

	if err != nil {
		return fmt.Errorf("failed to fetch existing assets: %w", err)
	}

	var uploadFiles []string

files:
	for _, file := range files {
		for _, asset := range assets {
			if *asset.Name == path.Base(file) {
				switch rc.FileExists {
				case "overwrite":
					// do nothing
				case "fail":
					return fmt.Errorf("asset file %s already exists", path.Base(file))
				case "skip":
					fmt.Printf("Skipping pre-existing %s artifact\n", *asset.Name)
					continue files
				default:
					return fmt.Errorf("internal error, unknown file_exist value %s", rc.FileExists)
				}
			}
		}

		uploadFiles = append(uploadFiles, file)
	}

	for _, file := range uploadFiles {
		handle, err := os.Open(file)

		if err != nil {
			return fmt.Errorf("failed to read %s artifact: %w", file, err)
		}

		for _, asset := range assets {
			if *asset.Name == path.Base(file) {
				if _, err := rc.Client.Repositories.DeleteReleaseAsset(rc.Context, rc.Owner, rc.Repo, *asset.ID); err != nil {
					return fmt.Errorf("failed to delete %s artifact: %w", file, err)
				}

				fmt.Printf("Successfully deleted old %s artifact\n", *asset.Name)
			}
		}

		uo := &github.UploadOptions{Name: path.Base(file)}

		if _, _, err = rc.Client.Repositories.UploadReleaseAsset(rc.Context, rc.Owner, rc.Repo, id, uo, handle); err != nil {
			return fmt.Errorf("failed to upload %s artifact: %w", file, err)
		}

		fmt.Printf("Successfully uploaded %s artifact\n", file)
	}

	return nil
}
<commit_msg>feature: consider every type of release (real, pre, draft)<commit_after>// Copyright (c) 2020, the Drone Plugins project authors.
// Please see the AUTHORS file for details. All rights reserved.
// Use of this source code is governed by an Apache 2.0 license that can be
// found in the LICENSE file.

package plugin

import (
	"context"
	"fmt"
	"os"
	"path"

	"github.com/google/go-github/v32/github"
)

// Release holds ties the drone env data and github client together.
type releaseClient struct {
	*github.Client
	context.Context
	Owner      string
	Repo       string
	Tag        string
	Draft      bool
	Prerelease bool
	FileExists string
	Title      string
	Note       string
	Overwrite  bool
}

func (rc *releaseClient) buildRelease() (*github.RepositoryRelease, error) {
	// first attempt to get a release by that tag
	release, err := rc.getRelease()

	if err != nil {
		return nil, fmt.Errorf("failed to retrieve a release: %w", err)
	}

	if release == nil {
		// if no release was found by that tag, create a new one
		release, err = rc.newRelease()
	} else {
		// update release if exists
		release, err = rc.editRelease(*release)
	}

	if err != nil {
		return nil, fmt.Errorf("failed to create or edit a release: %w", err)
	}

	return release, nil
}

func (rc *releaseClient) getRelease() (*github.RepositoryRelease, error) {

	listOpts := &github.ListOptions{PerPage: 10}

	for {
		// get list of releases (10 releases per page)
		releases, resp, err := rc.Client.Repositories.ListReleases(rc.Context, rc.Owner, rc.Repo, listOpts)
		if err != nil {
			return nil, fmt.Errorf("failed to list releases: %w", err)
		}

		// browse through current release page
		for _, release := range releases {

			// return release associated to the given tag (can only be one)
			if release.GetTagName() == rc.Tag {
				fmt.Printf("Found release %d for tag %s\n", release.GetID(), release.GetTagName())
				return release, nil
			}
		}

		// end of list found without finding a matching release
		if resp.NextPage == 0 {
			fmt.Println("no existing release (draft) found for the given tag")
			return nil, nil
		}

		// go to next page in the next iteration
		listOpts.Page = resp.NextPage
	}
}

func (rc *releaseClient) editRelease(targetRelease github.RepositoryRelease) (*github.RepositoryRelease, error) {
	sourceRelease := &github.RepositoryRelease{}

	if rc.Overwrite {
		sourceRelease.Name = &rc.Title
		sourceRelease.Body = &rc.Note
	}

	// only potentially change the draft value, if it's a draft right now
	// i.e. a drafted release will be published, but a release won't be unpublished
	if targetRelease.GetDraft() {
		fmt.Printf("DRAFT: %+v\n", rc.Draft)
		if !rc.Draft {
			fmt.Println("Publishing a release draft")
		}
		sourceRelease.Draft = &rc.Draft
	}

	modifiedRelease, _, err := rc.Client.Repositories.EditRelease(rc.Context, rc.Owner, rc.Repo, targetRelease.GetID(), sourceRelease)

	if err != nil {
		return nil, fmt.Errorf("failed to update release: %w", err)
	}

	fmt.Printf("Successfully updated %s release\n", rc.Tag)
	return modifiedRelease, nil
}

func (rc *releaseClient) newRelease() (*github.RepositoryRelease, error) {
	rr := &github.RepositoryRelease{
		TagName:    github.String(rc.Tag),
		Draft:      &rc.Draft,
		Prerelease: &rc.Prerelease,
		Name:       &rc.Title,
		Body:       &rc.Note,
	}

	if *rr.Prerelease {
		fmt.Printf("Release %s identified as a pre-release\n", rc.Tag)
	} else {
		fmt.Printf("Release %s identified as a full release\n", rc.Tag)
	}

	if *rr.Draft {
		fmt.Printf("Release %s will be created as draft (unpublished) release\n", rc.Tag)
	} else {
		fmt.Printf("Release %s will be created and published\n", rc.Tag)
	}

	release, _, err := rc.Client.Repositories.CreateRelease(rc.Context, rc.Owner, rc.Repo, rr)

	if err != nil {
		return nil, fmt.Errorf("failed to create release: %w", err)
	}

	fmt.Printf("Successfully created %s release\n", rc.Tag)
	return release, nil
}

func (rc *releaseClient) uploadFiles(id int64, files []string) error {
	assets, _, err := rc.Client.Repositories.ListReleaseAssets(rc.Context, rc.Owner, rc.Repo, id, &github.ListOptions{})

	if err != nil {
		return fmt.Errorf("failed to fetch existing assets: %w", err)
	}

	var uploadFiles []string

files:
	for _, file := range files {
		for _, asset := range assets {
			if *asset.Name == path.Base(file) {
				switch rc.FileExists {
				case "overwrite":
					// do nothing
				case "fail":
					return fmt.Errorf("asset file %s already exists", path.Base(file))
				case "skip":
					fmt.Printf("Skipping pre-existing %s artifact\n", *asset.Name)
					continue files
				default:
					return fmt.Errorf("internal error, unknown file_exist value %s", rc.FileExists)
				}
			}
		}

		uploadFiles = append(uploadFiles, file)
	}

	for _, file := range uploadFiles {
		handle, err := os.Open(file)

		if err != nil {
			return fmt.Errorf("failed to read %s artifact: %w", file, err)
		}

		for _, asset := range assets {
			if *asset.Name == path.Base(file) {
				if _, err := rc.Client.Repositories.DeleteReleaseAsset(rc.Context, rc.Owner, rc.Repo, *asset.ID); err != nil {
					return fmt.Errorf("failed to delete %s artifact: %w", file, err)
				}

				fmt.Printf("Successfully deleted old %s artifact\n", *asset.Name)
			}
		}

		uo := &github.UploadOptions{Name: path.Base(file)}

		if _, _, err = rc.Client.Repositories.UploadReleaseAsset(rc.Context, rc.Owner, rc.Repo, id, uo, handle); err != nil {
			return fmt.Errorf("failed to upload %s artifact: %w", file, err)
		}

		fmt.Printf("Successfully uploaded %s artifact\n", file)
	}

	return nil
}
<|endoftext|>


<commit_before>package rdb

import (
	"log"
	"os"
	"testing"
	"time"

	gorethink "gopkg.in/dancannon/gorethink.v2"

	"github.com/deskr/gopkg/internal/dock"
	docker "github.com/fsouza/go-dockerclient"
)

func TestMain(m *testing.M) {
	conf := dock.Config{}
	conf.Image = "rethinkdb:latest"
	conf.Tty = true
	conf.OpenStdin = true
	conf.ExposedPorts = map[docker.Port]struct{}{
		"28015/tcp": {},
	}
	conf.PortBindings = map[docker.Port][]docker.PortBinding{
		"28015/tcp": []docker.PortBinding{
			{
				HostPort: "28015",
			},
		},
	}
	_, closer, err := dock.Run(conf)
	if err != nil {
		log.Fatalf("Failed to run RethinkDB container: %+v", err)
		return
	}

	res := m.Run()

	closer()

	os.Exit(res)
}

func TestOpenSession(t *testing.T) {
	_, err := OpenSession(gorethink.ConnectOpts{
		Address:  "localhost:28015",
		Database: "test",
	}, time.Second*5)
	if err != nil {
		t.Errorf("Failed to open session: %v", err)
		return
	}
}

// TestOpenSessionNoWait works only if it get's tested after another connection has been made
func TestOpenSessionNoWait(t *testing.T) {
	_, err := OpenSession(gorethink.ConnectOpts{
		Address:  "localhost:28015",
		Database: "test",
	}, 0)
	if err != nil {
		t.Errorf("Failed to open session: %v", err)
		return
	}
}
<commit_msg>comment<commit_after>package rdb

import (
	"log"
	"os"
	"testing"
	"time"

	gorethink "gopkg.in/dancannon/gorethink.v2"

	"github.com/deskr/gopkg/internal/dock"
	docker "github.com/fsouza/go-dockerclient"
)

func TestMain(m *testing.M) {
	conf := dock.Config{}
	conf.Image = "rethinkdb:latest"
	conf.Tty = true
	conf.OpenStdin = true

	// Using "Docker for Mac" - so no connection from host -> container :(
	conf.ExposedPorts = map[docker.Port]struct{}{
		"28015/tcp": {},
	}
	conf.PortBindings = map[docker.Port][]docker.PortBinding{
		"28015/tcp": []docker.PortBinding{
			{
				HostPort: "28015",
			},
		},
	}
	_, closer, err := dock.Run(conf)
	if err != nil {
		log.Fatalf("Failed to run RethinkDB container: %+v", err)
		return
	}

	res := m.Run()

	closer()

	os.Exit(res)
}

func TestOpenSession(t *testing.T) {
	_, err := OpenSession(gorethink.ConnectOpts{
		Address:  "localhost:28015",
		Database: "test",
	}, time.Second*5)
	if err != nil {
		t.Errorf("Failed to open session: %v", err)
		return
	}
}

// TestOpenSessionNoWait works only if it get's tested after another connection has been made
func TestOpenSessionNoWait(t *testing.T) {
	_, err := OpenSession(gorethink.ConnectOpts{
		Address:  "localhost:28015",
		Database: "test",
	}, 0)
	if err != nil {
		t.Errorf("Failed to open session: %v", err)
		return
	}
}
<|endoftext|>


<commit_before><commit_msg>internal/godoc/dochtml: add content for empty sections<commit_after><|endoftext|>


<commit_before>// Copyright 2018 Granitic. All rights reserved.
// Use of this source code is governed by an Apache 2.0 license that can be found in the LICENSE file at the root of this project.
package instrument

import (
	"context"
	"runtime"
)

// Additional is used as a flag to indicate what additional data being passed to the Instrumentor represents. These are
// used by Granitic to pass additional data about a request into a Instrumentor that is not known at the point instrumentation starts
type Additional uint

const (
	REQUEST_ID      Additional = iota //string representation of a unique ID for the request
	REQUEST_VERSION                   //instance of ws.RequiredVersion
	USER_IDENTITY                     //instance of iam.ClientIdentity
	HANDLER                           //The handler that is processing the request (*ws.Handler)
)

// Instrumentor is implemented by types that can add additional information to a request that is being instrumented in
// the form of sub/child events that are instrumented separately and additional framework data that was not available when instrumentation
// began.
//
// Interfaces are not expected to be explicitly goroutine safe - the Fork and Integrate methods are intended for use when the
// request under instrumentation spawns new goroutines
type Instrumentor interface {
	// StartEvent indicates that a new instrumentable activity has begun with the supplied ID. Implementation specific additional
	// information about the event can be supplied via the metadata varg
	//
	// The function returned by this method should be called when the event ends. This facilitates a pattern like defer StartEvent(id)()
	StartEvent(id string, metadata ...interface{}) EndEvent

	// Fork creates a new context and Instrumentor suitable for passing to a child goroutine
	Fork(ctx context.Context) (context.Context, Instrumentor)

	//Integrate incorporates the data from a forked Instrumentor that was passed to a goroutine
	Integrate(instrumentor Instrumentor)

	//Amend allows Granitic to provide additional information about the request that was not available when instrumentation started
	Amend(additional Additional, value interface{})
}

type ctxKey int

const instrumentorKey ctxKey = 0

// InstrumentorFromContext returns a Instrumentor from the supplied context, or nil if no Instrumentor
// is present
func InstrumentorFromContext(ctx context.Context) Instrumentor {

	v := ctx.Value(instrumentorKey)

	if ri, found := v.(Instrumentor); found {
		return ri
	} else {
		return nil
	}
}

// AddInstrumentorToContext stores the supplied Instrumentor in a new context, derived from the supplied context.
func AddInstrumentorToContext(ctx context.Context, ri Instrumentor) context.Context {
	return context.WithValue(ctx, instrumentorKey, ri)
}

type EndEvent func()

// Event is convenience function that calls InstrumentorFromContext then StartEvent. This function
// fails silently if the result of InstrumentorFromContext is nil (e.g there is no Instrumentor in the context)
func Event(ctx context.Context, id string, metadata ...interface{}) EndEvent {
	if ri := InstrumentorFromContext(ctx); ri == nil {
		return func() {}
	} else {
		return ri.StartEvent(id, metadata...)
	}
}

// Method is a convenience function that calls Event with the name of the calling function as the ID.
// The format of the method name will be /path/to/package.(type).FunctionName
//
// This function fails silently if the result of InstrumentorFromContext is nil (e.g there is no Instrumentor in the context)
func Method(ctx context.Context, metadata ...interface{}) EndEvent {
	pc := make([]uintptr, 1)
	n := runtime.Callers(2, pc)
	frames := runtime.CallersFrames(pc[:n])
	frame, _ := frames.Next()

	return Event(ctx, frame.Function, metadata...)

}
<commit_msg>Shorter method names in instrumentation traces<commit_after>// Copyright 2018 Granitic. All rights reserved.
// Use of this source code is governed by an Apache 2.0 license that can be found in the LICENSE file at the root of this project.
package instrument

import (
	"context"
	"runtime"
	"strings"
)

// Additional is used as a flag to indicate what additional data being passed to the Instrumentor represents. These are
// used by Granitic to pass additional data about a request into a Instrumentor that is not known at the point instrumentation starts
type Additional uint

const (
	REQUEST_ID      Additional = iota //string representation of a unique ID for the request
	REQUEST_VERSION                   //instance of ws.RequiredVersion
	USER_IDENTITY                     //instance of iam.ClientIdentity
	HANDLER                           //The handler that is processing the request (*ws.Handler)
)

// Instrumentor is implemented by types that can add additional information to a request that is being instrumented in
// the form of sub/child events that are instrumented separately and additional framework data that was not available when instrumentation
// began.
//
// Interfaces are not expected to be explicitly goroutine safe - the Fork and Integrate methods are intended for use when the
// request under instrumentation spawns new goroutines
type Instrumentor interface {
	// StartEvent indicates that a new instrumentable activity has begun with the supplied ID. Implementation specific additional
	// information about the event can be supplied via the metadata varg
	//
	// The function returned by this method should be called when the event ends. This facilitates a pattern like defer StartEvent(id)()
	StartEvent(id string, metadata ...interface{}) EndEvent

	// Fork creates a new context and Instrumentor suitable for passing to a child goroutine
	Fork(ctx context.Context) (context.Context, Instrumentor)

	//Integrate incorporates the data from a forked Instrumentor that was passed to a goroutine
	Integrate(instrumentor Instrumentor)

	//Amend allows Granitic to provide additional information about the request that was not available when instrumentation started
	Amend(additional Additional, value interface{})
}

type ctxKey int

const instrumentorKey ctxKey = 0

// InstrumentorFromContext returns a Instrumentor from the supplied context, or nil if no Instrumentor
// is present
func InstrumentorFromContext(ctx context.Context) Instrumentor {

	v := ctx.Value(instrumentorKey)

	if ri, found := v.(Instrumentor); found {
		return ri
	} else {
		return nil
	}
}

// AddInstrumentorToContext stores the supplied Instrumentor in a new context, derived from the supplied context.
func AddInstrumentorToContext(ctx context.Context, ri Instrumentor) context.Context {
	return context.WithValue(ctx, instrumentorKey, ri)
}

type EndEvent func()

// Event is convenience function that calls InstrumentorFromContext then StartEvent. This function
// fails silently if the result of InstrumentorFromContext is nil (e.g there is no Instrumentor in the context)
func Event(ctx context.Context, id string, metadata ...interface{}) EndEvent {
	if ri := InstrumentorFromContext(ctx); ri == nil {
		return func() {}
	} else {
		return ri.StartEvent(id, metadata...)
	}
}

// Method is a convenience function that calls Event with the name of the calling function as the ID.
// The format of the method name will be /path/to/package.(type).FunctionName
//
// This function fails silently if the result of InstrumentorFromContext is nil (e.g there is no Instrumentor in the context)
func Method(ctx context.Context, metadata ...interface{}) EndEvent {
	pc := make([]uintptr, 1)
	n := runtime.Callers(2, pc)
	frames := runtime.CallersFrames(pc[:n])
	frame, _ := frames.Next()

	c := strings.Split(frame.Function, "/")

	return Event(ctx, c[len(c)-1], metadata...)

}
<|endoftext|>


<commit_before>package service

import (
	"context"
	"errors"
	"fmt"
	"log"
	"strings"
	"time"

	"github.com/sanity-io/litter"
)

var (
	// ErrInvalidContent is used for invalid content.
	ErrInvalidContent = errors.New("invalid content")
	// ErrInvalidSpoiler used for invalid spoiler title.
	ErrInvalidSpoiler = errors.New("invalid spoiler")
)

// Post model.
type Post struct {
	ID        int64     `json:"id"`
	UserID    int64     `json:"-"`
	Content   string    `json:"content"`
	SpoilerOf *string   `json:"spoilerOf"`
	NSFW      bool      `json:"nsfw"`
	CreatedAt time.Time `json:"createdAt"`
	User      *User     `json:"user,omitempty"`
	Mine      bool      `json:"mine"`
}

// CreatePost publishes a post the the user timeline and fan-outs it to his followers.
func (s *Service) CreatePost(
	ctx context.Context,
	content string,
	spoilerOf *string,
	nsfw bool,
) (TimelineItem, error) {
	var ti TimelineItem
	uid, ok := ctx.Value(KeyAuthUserID).(int64)
	if !ok {
		return ti, ErrUnauthenticated
	}

	content = strings.TrimSpace(content)
	if content == "" || len([]rune(content)) > 480 {
		return ti, ErrInvalidContent
	}

	if spoilerOf != nil {
		*spoilerOf = strings.TrimSpace(*spoilerOf)
		if *spoilerOf == "" || len([]rune(*spoilerOf)) > 64 {
			return ti, ErrInvalidSpoiler
		}
	}

	tx, err := s.db.BeginTx(ctx, nil)
	if err != nil {
		return ti, fmt.Errorf("could not begin tx: %v", err)
	}

	defer tx.Rollback()

	query := "INSERT INTO posts (user_id, content, spoiler_of, nsfw) VALUES ($1, $2, $3, $4) " +
		"RETURNING id, created_at"
	if err = tx.QueryRowContext(ctx, query, uid, content, spoilerOf, nsfw).
		Scan(&ti.Post.ID, &ti.Post.CreatedAt); err != nil {
		return ti, fmt.Errorf("could not insert post: %v", err)
	}

	ti.Post.UserID = uid
	ti.Post.Content = content
	ti.Post.SpoilerOf = spoilerOf
	ti.Post.NSFW = nsfw
	ti.Post.Mine = true

	query = "INSERT INTO timeline (user_id, post_id) VALUES ($1, $2) RETURNING id"
	if err = tx.QueryRowContext(ctx, query, uid, ti.Post.ID).Scan(&ti.ID); err != nil {
		return ti, fmt.Errorf("could not insert timeline item: %v", err)
	}

	ti.UserID = uid
	ti.PostID = ti.Post.ID

	if err = tx.Commit(); err != nil {
		return ti, fmt.Errorf("could not commit to create post: %v", err)
	}

	go func(p Post) {
		u, err := s.userByID(context.Background(), p.UserID)
		if err != nil {
			log.Printf("could not get post user: %v\n", err)
			return
		}

		p.User = &u
		p.Mine = false

		tt, err := s.fanoutPost(p)
		if err != nil {
			log.Printf("could not fanout post: %v\n", err)
			return
		}

		for _, ti = range tt {
			log.Println(litter.Sdump(ti))
			// TODO: broadcast timeline items.
		}
	}(ti.Post)

	// TODO: notify each mentioned user in posts.

	return ti, nil
}

func (s *Service) fanoutPost(p Post) ([]TimelineItem, error) {
	query := "INSERT INTO timeline (user_id, post_id) " +
		"SELECT follower_id, $1 FROM follows WHERE followee_id = $2 " +
		"RETURNING id, user_id"
	rows, err := s.db.Query(query, p.ID, p.UserID)
	if err != nil {
		return nil, fmt.Errorf("could not insert timeline: %v", err)
	}

	defer rows.Close()

	tt := []TimelineItem{}
	for rows.Next() {
		var ti TimelineItem
		if err = rows.Scan(&ti.ID, &ti.UserID); err != nil {
			return nil, fmt.Errorf("could not scan timeline item: %v", err)
		}

		ti.PostID = p.ID
		ti.Post = p
		tt = append(tt, ti)
	}

	if err = rows.Err(); err != nil {
		return nil, fmt.Errorf("could not iterate timeline rows: %v", err)
	}

	return tt, nil
}
<commit_msg>fix: removed posts fanout log<commit_after>package service

import (
	"context"
	"errors"
	"fmt"
	"log"
	"strings"
	"time"
)

var (
	// ErrInvalidContent is used for invalid content.
	ErrInvalidContent = errors.New("invalid content")
	// ErrInvalidSpoiler used for invalid spoiler title.
	ErrInvalidSpoiler = errors.New("invalid spoiler")
)

// Post model.
type Post struct {
	ID        int64     `json:"id"`
	UserID    int64     `json:"-"`
	Content   string    `json:"content"`
	SpoilerOf *string   `json:"spoilerOf"`
	NSFW      bool      `json:"nsfw"`
	CreatedAt time.Time `json:"createdAt"`
	User      *User     `json:"user,omitempty"`
	Mine      bool      `json:"mine"`
}

// CreatePost publishes a post the the user timeline and fan-outs it to his followers.
func (s *Service) CreatePost(
	ctx context.Context,
	content string,
	spoilerOf *string,
	nsfw bool,
) (TimelineItem, error) {
	var ti TimelineItem
	uid, ok := ctx.Value(KeyAuthUserID).(int64)
	if !ok {
		return ti, ErrUnauthenticated
	}

	content = strings.TrimSpace(content)
	if content == "" || len([]rune(content)) > 480 {
		return ti, ErrInvalidContent
	}

	if spoilerOf != nil {
		*spoilerOf = strings.TrimSpace(*spoilerOf)
		if *spoilerOf == "" || len([]rune(*spoilerOf)) > 64 {
			return ti, ErrInvalidSpoiler
		}
	}

	tx, err := s.db.BeginTx(ctx, nil)
	if err != nil {
		return ti, fmt.Errorf("could not begin tx: %v", err)
	}

	defer tx.Rollback()

	query := "INSERT INTO posts (user_id, content, spoiler_of, nsfw) VALUES ($1, $2, $3, $4) " +
		"RETURNING id, created_at"
	if err = tx.QueryRowContext(ctx, query, uid, content, spoilerOf, nsfw).
		Scan(&ti.Post.ID, &ti.Post.CreatedAt); err != nil {
		return ti, fmt.Errorf("could not insert post: %v", err)
	}

	ti.Post.UserID = uid
	ti.Post.Content = content
	ti.Post.SpoilerOf = spoilerOf
	ti.Post.NSFW = nsfw
	ti.Post.Mine = true

	query = "INSERT INTO timeline (user_id, post_id) VALUES ($1, $2) RETURNING id"
	if err = tx.QueryRowContext(ctx, query, uid, ti.Post.ID).Scan(&ti.ID); err != nil {
		return ti, fmt.Errorf("could not insert timeline item: %v", err)
	}

	ti.UserID = uid
	ti.PostID = ti.Post.ID

	if err = tx.Commit(); err != nil {
		return ti, fmt.Errorf("could not commit to create post: %v", err)
	}

	go func(p Post) {
		u, err := s.userByID(context.Background(), p.UserID)
		if err != nil {
			log.Printf("could not get post user: %v\n", err)
			return
		}

		p.User = &u
		p.Mine = false

		_, err = s.fanoutPost(p)
		if err != nil {
			log.Printf("could not fanout post: %v\n", err)
			return
		}

		// TODO: broadcast timeline items.
	}(ti.Post)

	// TODO: notify each mentioned user in posts.

	return ti, nil
}

func (s *Service) fanoutPost(p Post) ([]TimelineItem, error) {
	query := "INSERT INTO timeline (user_id, post_id) " +
		"SELECT follower_id, $1 FROM follows WHERE followee_id = $2 " +
		"RETURNING id, user_id"
	rows, err := s.db.Query(query, p.ID, p.UserID)
	if err != nil {
		return nil, fmt.Errorf("could not insert timeline: %v", err)
	}

	defer rows.Close()

	tt := []TimelineItem{}
	for rows.Next() {
		var ti TimelineItem
		if err = rows.Scan(&ti.ID, &ti.UserID); err != nil {
			return nil, fmt.Errorf("could not scan timeline item: %v", err)
		}

		ti.PostID = p.ID
		ti.Post = p
		tt = append(tt, ti)
	}

	if err = rows.Err(); err != nil {
		return nil, fmt.Errorf("could not iterate timeline rows: %v", err)
	}

	return tt, nil
}
<|endoftext|>