<commit_before>// Copyright 2015 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"flag"
	"fmt"
	"net"
	"os"
	"os/signal"
	"path/filepath"
	"strings"
	"sync"
	"syscall"

	"github.com/coreos/flannel/Godeps/_workspace/src/github.com/coreos/go-systemd/daemon"
	log "github.com/coreos/flannel/Godeps/_workspace/src/github.com/golang/glog"
	"github.com/coreos/flannel/Godeps/_workspace/src/golang.org/x/net/context"
	"github.com/coreos/flannel/backend"
	"github.com/coreos/flannel/network"
	"github.com/coreos/flannel/pkg/ip"
	"github.com/coreos/flannel/remote"
	"github.com/coreos/flannel/subnet"
)

type CmdLineOpts struct {
	etcdEndpoints string
	etcdPrefix    string
	etcdKeyfile   string
	etcdCertfile  string
	etcdCAFile    string
	help          bool
	version       bool
	ipMasq        bool
	subnetFile    string
	subnetDir     string
	iface         string
	listen        string
	remote        string
	networks      string
}

var opts CmdLineOpts

func init() {
	flag.StringVar(&opts.etcdEndpoints, "etcd-endpoints", "http://127.0.0.1:4001,http://127.0.0.1:2379", "a comma-delimited list of etcd endpoints")
	flag.StringVar(&opts.etcdPrefix, "etcd-prefix", "/coreos.com/network", "etcd prefix")
	flag.StringVar(&opts.etcdKeyfile, "etcd-keyfile", "", "SSL key file used to secure etcd communication")
	flag.StringVar(&opts.etcdCertfile, "etcd-certfile", "", "SSL certification file used to secure etcd communication")
	flag.StringVar(&opts.etcdCAFile, "etcd-cafile", "", "SSL Certificate Authority file used to secure etcd communication")
	flag.StringVar(&opts.subnetFile, "subnet-file", "/run/flannel/subnet.env", "filename where env variables (subnet, MTU, ... ) will be written to")
	flag.StringVar(&opts.subnetDir, "subnet-dir", "/run/flannel/networks", "directory where files with env variables (subnet, MTU, ...) will be written to")
	flag.StringVar(&opts.iface, "iface", "", "interface to use (IP or name) for inter-host communication")
	flag.StringVar(&opts.listen, "listen", "", "run as server and listen on specified address (e.g. ':8080')")
	flag.StringVar(&opts.remote, "remote", "", "run as client and connect to server on specified address (e.g. '10.1.2.3:8080')")
	flag.StringVar(&opts.networks, "networks", "", "run in multi-network mode and service the specified networks")
	flag.BoolVar(&opts.ipMasq, "ip-masq", false, "setup IP masquerade rule for traffic destined outside of overlay network")
	flag.BoolVar(&opts.help, "help", false, "print this message")
	flag.BoolVar(&opts.version, "version", false, "print version and exit")
}

// TODO: This is yet another copy (others found in etcd, fleet) -- Pull it out!
// flagsFromEnv parses all registered flags in the given flagset,
// and if they are not already set it attempts to set their values from
// environment variables. Environment variables take the name of the flag but
// are UPPERCASE, have the given prefix, and any dashes are replaced by
// underscores - for example: some-flag => PREFIX_SOME_FLAG
func flagsFromEnv(prefix string, fs *flag.FlagSet) {
	alreadySet := make(map[string]bool)
	fs.Visit(func(f *flag.Flag) {
		alreadySet[f.Name] = true
	})
	fs.VisitAll(func(f *flag.Flag) {
		if !alreadySet[f.Name] {
			key := strings.ToUpper(prefix + "_" + strings.Replace(f.Name, "-", "_", -1))
			val := os.Getenv(key)
			if val != "" {
				fs.Set(f.Name, val)
			}
		}
	})
}

func writeSubnetFile(path string, sn *backend.SubnetDef) error {
	dir, name := filepath.Split(path)
	os.MkdirAll(dir, 0755)

	tempFile := filepath.Join(dir, "."+name)
	f, err := os.Create(tempFile)
	if err != nil {
		return err
	}

	// Write out the first usable IP by incrementing
	// sn.IP by one
	sn.Net.IP += 1

	fmt.Fprintf(f, "FLANNEL_SUBNET=%s\n", sn.Net)
	fmt.Fprintf(f, "FLANNEL_MTU=%d\n", sn.MTU)
	_, err = fmt.Fprintf(f, "FLANNEL_IPMASQ=%v\n", opts.ipMasq)
	f.Close()
	if err != nil {
		return err
	}

	// rename(2) the temporary file to the desired location so that it becomes
	// atomically visible with the contents
	return os.Rename(tempFile, path)
}

func lookupIface() (*net.Interface, net.IP, error) {
	var iface *net.Interface
	var ipaddr net.IP
	var err error

	if len(opts.iface) > 0 {
		if ipaddr = net.ParseIP(opts.iface); ipaddr != nil {
			iface, err = ip.GetInterfaceByIP(ipaddr)
			if err != nil {
				return nil, nil, fmt.Errorf("Error looking up interface %s: %s", opts.iface, err)
			}
		} else {
			iface, err = net.InterfaceByName(opts.iface)
			if err != nil {
				return nil, nil, fmt.Errorf("Error looking up interface %s: %s", opts.iface, err)
			}
		}
	} else {
		log.Info("Determining IP address of default interface")
		if iface, err = ip.GetDefaultGatewayIface(); err != nil {
			return nil, nil, fmt.Errorf("Failed to get default interface: %s", err)
		}
	}

	if ipaddr == nil {
		ipaddr, err = ip.GetIfaceIP4Addr(iface)
		if err != nil {
			return nil, nil, fmt.Errorf("Failed to find IPv4 address for interface %s", iface.Name)
		}
	}

	return iface, ipaddr, nil
}

func isMultiNetwork() bool {
	return len(opts.networks) > 0
}

func newSubnetManager() (subnet.Manager, error) {
	if opts.remote != "" {
		return remote.NewRemoteManager(opts.remote), nil
	}

	cfg := &subnet.EtcdConfig{
		Endpoints: strings.Split(opts.etcdEndpoints, ","),
		Keyfile:   opts.etcdKeyfile,
		Certfile:  opts.etcdCertfile,
		CAFile:    opts.etcdCAFile,
		Prefix:    opts.etcdPrefix,
	}

	return subnet.NewEtcdManager(cfg)
}

func initAndRun(ctx context.Context, sm subnet.Manager, netnames []string) {
	iface, ipaddr, err := lookupIface()
	if err != nil {
		log.Error(err)
		return
	}

	if iface.MTU == 0 {
		log.Errorf("Failed to determine MTU for %s interface", ipaddr)
		return
	}

	log.Infof("Using %s as external interface", ipaddr)

	nets := []*network.Network{}
	for _, n := range netnames {
		nets = append(nets, network.New(sm, n, opts.ipMasq))
	}

	wg := sync.WaitGroup{}

	for _, n := range nets {
		go func(n *network.Network) {
			wg.Add(1)
			defer wg.Done()

			sn := n.Init(ctx, iface, ipaddr)
			if sn != nil {
				if isMultiNetwork() {
					path := filepath.Join(opts.subnetDir, n.Name) + ".env"
					if err := writeSubnetFile(path, sn); err != nil {
						return
					}
				} else {
					if err := writeSubnetFile(opts.subnetFile, sn); err != nil {
						return
					}
					daemon.SdNotify("READY=1")
				}

				n.Run(ctx)
				log.Infof("%v exited", n.Name)
			}
		}(n)
	}

	wg.Wait()
}

func main() {
	// glog will log to tmp files by default. override so all entries
	// can flow into journald (if running under systemd)
	flag.Set("logtostderr", "true")

	// now parse command line args
	flag.Parse()

	if opts.help {
		fmt.Fprintf(os.Stderr, "Usage: %s [OPTION]...\n", os.Args[0])
		flag.PrintDefaults()
		os.Exit(0)
	}

	if opts.version {
		fmt.Fprintln(os.Stderr, Version)
		os.Exit(0)
	}

	flagsFromEnv("FLANNELD", flag.CommandLine)

	sm, err := newSubnetManager()
	if err != nil {
		log.Error("Failed to create SubnetManager: ", err)
		os.Exit(1)
	}

	var runFunc func(ctx context.Context)

	if opts.listen != "" {
		if opts.remote != "" {
			log.Error("--listen and --remote are mutually exclusive")
			os.Exit(1)
		}
		log.Info("running as server")
		runFunc = func(ctx context.Context) {
			remote.RunServer(ctx, sm, opts.listen)
		}
	} else {
		networks := strings.Split(opts.networks, ",")
		if len(networks) == 0 {
			networks = append(networks, "")
		}
		runFunc = func(ctx context.Context) {
			initAndRun(ctx, sm, networks)
		}
	}

	// Register for SIGINT and SIGTERM
	log.Info("Installing signal handlers")
	sigs := make(chan os.Signal, 1)
	signal.Notify(sigs, os.Interrupt, syscall.SIGTERM)

	ctx, cancel := context.WithCancel(context.Background())

	wg := sync.WaitGroup{}
	wg.Add(1)
	go func() {
		runFunc(ctx)
		wg.Done()
	}()

	<-sigs
	// unregister to get default OS nuke behaviour in case we don't exit cleanly
	signal.Stop(sigs)

	log.Info("Exiting...")
	cancel()

	wg.Wait()
}
<commit_msg>Don't allow extra args<commit_after>// Copyright 2015 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"flag"
	"fmt"
	"net"
	"os"
	"os/signal"
	"path/filepath"
	"strings"
	"sync"
	"syscall"

	"github.com/coreos/flannel/Godeps/_workspace/src/github.com/coreos/go-systemd/daemon"
	log "github.com/coreos/flannel/Godeps/_workspace/src/github.com/golang/glog"
	"github.com/coreos/flannel/Godeps/_workspace/src/golang.org/x/net/context"
	"github.com/coreos/flannel/backend"
	"github.com/coreos/flannel/network"
	"github.com/coreos/flannel/pkg/ip"
	"github.com/coreos/flannel/remote"
	"github.com/coreos/flannel/subnet"
)

type CmdLineOpts struct {
	etcdEndpoints string
	etcdPrefix    string
	etcdKeyfile   string
	etcdCertfile  string
	etcdCAFile    string
	help          bool
	version       bool
	ipMasq        bool
	subnetFile    string
	subnetDir     string
	iface         string
	listen        string
	remote        string
	networks      string
}

var opts CmdLineOpts

func init() {
	flag.StringVar(&opts.etcdEndpoints, "etcd-endpoints", "http://127.0.0.1:4001,http://127.0.0.1:2379", "a comma-delimited list of etcd endpoints")
	flag.StringVar(&opts.etcdPrefix, "etcd-prefix", "/coreos.com/network", "etcd prefix")
	flag.StringVar(&opts.etcdKeyfile, "etcd-keyfile", "", "SSL key file used to secure etcd communication")
	flag.StringVar(&opts.etcdCertfile, "etcd-certfile", "", "SSL certification file used to secure etcd communication")
	flag.StringVar(&opts.etcdCAFile, "etcd-cafile", "", "SSL Certificate Authority file used to secure etcd communication")
	flag.StringVar(&opts.subnetFile, "subnet-file", "/run/flannel/subnet.env", "filename where env variables (subnet, MTU, ... ) will be written to")
	flag.StringVar(&opts.subnetDir, "subnet-dir", "/run/flannel/networks", "directory where files with env variables (subnet, MTU, ...) will be written to")
	flag.StringVar(&opts.iface, "iface", "", "interface to use (IP or name) for inter-host communication")
	flag.StringVar(&opts.listen, "listen", "", "run as server and listen on specified address (e.g. ':8080')")
	flag.StringVar(&opts.remote, "remote", "", "run as client and connect to server on specified address (e.g. '10.1.2.3:8080')")
	flag.StringVar(&opts.networks, "networks", "", "run in multi-network mode and service the specified networks")
	flag.BoolVar(&opts.ipMasq, "ip-masq", false, "setup IP masquerade rule for traffic destined outside of overlay network")
	flag.BoolVar(&opts.help, "help", false, "print this message")
	flag.BoolVar(&opts.version, "version", false, "print version and exit")
}

// TODO: This is yet another copy (others found in etcd, fleet) -- Pull it out!
// flagsFromEnv parses all registered flags in the given flagset,
// and if they are not already set it attempts to set their values from
// environment variables. Environment variables take the name of the flag but
// are UPPERCASE, have the given prefix, and any dashes are replaced by
// underscores - for example: some-flag => PREFIX_SOME_FLAG
func flagsFromEnv(prefix string, fs *flag.FlagSet) {
	alreadySet := make(map[string]bool)
	fs.Visit(func(f *flag.Flag) {
		alreadySet[f.Name] = true
	})
	fs.VisitAll(func(f *flag.Flag) {
		if !alreadySet[f.Name] {
			key := strings.ToUpper(prefix + "_" + strings.Replace(f.Name, "-", "_", -1))
			val := os.Getenv(key)
			if val != "" {
				fs.Set(f.Name, val)
			}
		}
	})
}

func writeSubnetFile(path string, sn *backend.SubnetDef) error {
	dir, name := filepath.Split(path)
	os.MkdirAll(dir, 0755)

	tempFile := filepath.Join(dir, "."+name)
	f, err := os.Create(tempFile)
	if err != nil {
		return err
	}

	// Write out the first usable IP by incrementing
	// sn.IP by one
	sn.Net.IP += 1

	fmt.Fprintf(f, "FLANNEL_SUBNET=%s\n", sn.Net)
	fmt.Fprintf(f, "FLANNEL_MTU=%d\n", sn.MTU)
	_, err = fmt.Fprintf(f, "FLANNEL_IPMASQ=%v\n", opts.ipMasq)
	f.Close()
	if err != nil {
		return err
	}

	// rename(2) the temporary file to the desired location so that it becomes
	// atomically visible with the contents
	return os.Rename(tempFile, path)
}

func lookupIface() (*net.Interface, net.IP, error) {
	var iface *net.Interface
	var ipaddr net.IP
	var err error

	if len(opts.iface) > 0 {
		if ipaddr = net.ParseIP(opts.iface); ipaddr != nil {
			iface, err = ip.GetInterfaceByIP(ipaddr)
			if err != nil {
				return nil, nil, fmt.Errorf("Error looking up interface %s: %s", opts.iface, err)
			}
		} else {
			iface, err = net.InterfaceByName(opts.iface)
			if err != nil {
				return nil, nil, fmt.Errorf("Error looking up interface %s: %s", opts.iface, err)
			}
		}
	} else {
		log.Info("Determining IP address of default interface")
		if iface, err = ip.GetDefaultGatewayIface(); err != nil {
			return nil, nil, fmt.Errorf("Failed to get default interface: %s", err)
		}
	}

	if ipaddr == nil {
		ipaddr, err = ip.GetIfaceIP4Addr(iface)
		if err != nil {
			return nil, nil, fmt.Errorf("Failed to find IPv4 address for interface %s", iface.Name)
		}
	}

	return iface, ipaddr, nil
}

func isMultiNetwork() bool {
	return len(opts.networks) > 0
}

func newSubnetManager() (subnet.Manager, error) {
	if opts.remote != "" {
		return remote.NewRemoteManager(opts.remote), nil
	}

	cfg := &subnet.EtcdConfig{
		Endpoints: strings.Split(opts.etcdEndpoints, ","),
		Keyfile:   opts.etcdKeyfile,
		Certfile:  opts.etcdCertfile,
		CAFile:    opts.etcdCAFile,
		Prefix:    opts.etcdPrefix,
	}

	return subnet.NewEtcdManager(cfg)
}

func initAndRun(ctx context.Context, sm subnet.Manager, netnames []string) {
	iface, ipaddr, err := lookupIface()
	if err != nil {
		log.Error(err)
		return
	}

	if iface.MTU == 0 {
		log.Errorf("Failed to determine MTU for %s interface", ipaddr)
		return
	}

	log.Infof("Using %s as external interface", ipaddr)

	nets := []*network.Network{}
	for _, n := range netnames {
		nets = append(nets, network.New(sm, n, opts.ipMasq))
	}

	wg := sync.WaitGroup{}

	for _, n := range nets {
		go func(n *network.Network) {
			wg.Add(1)
			defer wg.Done()

			sn := n.Init(ctx, iface, ipaddr)
			if sn != nil {
				if isMultiNetwork() {
					path := filepath.Join(opts.subnetDir, n.Name) + ".env"
					if err := writeSubnetFile(path, sn); err != nil {
						return
					}
				} else {
					if err := writeSubnetFile(opts.subnetFile, sn); err != nil {
						return
					}
					daemon.SdNotify("READY=1")
				}

				n.Run(ctx)
				log.Infof("%v exited", n.Name)
			}
		}(n)
	}

	wg.Wait()
}

func main() {
	// glog will log to tmp files by default. override so all entries
	// can flow into journald (if running under systemd)
	flag.Set("logtostderr", "true")

	// now parse command line args
	flag.Parse()

	if flag.NArg() > 0 || opts.help {
		fmt.Fprintf(os.Stderr, "Usage: %s [OPTION]...\n", os.Args[0])
		flag.PrintDefaults()
		os.Exit(0)
	}

	if opts.version {
		fmt.Fprintln(os.Stderr, Version)
		os.Exit(0)
	}

	flagsFromEnv("FLANNELD", flag.CommandLine)

	sm, err := newSubnetManager()
	if err != nil {
		log.Error("Failed to create SubnetManager: ", err)
		os.Exit(1)
	}

	var runFunc func(ctx context.Context)

	if opts.listen != "" {
		if opts.remote != "" {
			log.Error("--listen and --remote are mutually exclusive")
			os.Exit(1)
		}
		log.Info("running as server")
		runFunc = func(ctx context.Context) {
			remote.RunServer(ctx, sm, opts.listen)
		}
	} else {
		networks := strings.Split(opts.networks, ",")
		if len(networks) == 0 {
			networks = append(networks, "")
		}
		runFunc = func(ctx context.Context) {
			initAndRun(ctx, sm, networks)
		}
	}

	// Register for SIGINT and SIGTERM
	log.Info("Installing signal handlers")
	sigs := make(chan os.Signal, 1)
	signal.Notify(sigs, os.Interrupt, syscall.SIGTERM)

	ctx, cancel := context.WithCancel(context.Background())

	wg := sync.WaitGroup{}
	wg.Add(1)
	go func() {
		runFunc(ctx)
		wg.Done()
	}()

	<-sigs
	// unregister to get default OS nuke behaviour in case we don't exit cleanly
	signal.Stop(sigs)

	log.Info("Exiting...")
	cancel()

	wg.Wait()
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"image"
	"image/draw"
	"image/png"
	"io/ioutil"
	"log"
	"os"
	"path"
	"path/filepath"
	"sort"
	"strconv"
	"strings"
)

func main() {
	var space int
	var dim string

	flag.IntVar(&space, "space", 1, "space added between images")
	flag.StringVar(&dim, "dimensions", "1024x1024", "atlas size")

	flag.Parse()

	args := flag.Args()

	inputDir := args[0]
	outputName := args[1]

	dimX, dimY, err := parseDimensions(dim)
	if err != nil {
		log.Fatal(err)
	}

	files, err := ioutil.ReadDir(inputDir)
	if err != nil {
		log.Fatal(err)
	}

	sprites := make([]sprite, len(files))

	totalArea := 0

	for i := range sprites {
		s, err := readSprite(inputDir, files[i].Name(), space)
		if err != nil {
			log.Fatal(err)
		}
		totalArea += s.area
		sprites[i] = s
	}

	if totalArea > dimX*dimY {
		log.Fatalf("%s atlas to small", dim)
	}

	// we want to place the largest sprite first
	sort.Sort(sort.Reverse(ByArea(sprites)))

	// the final image
	img := image.NewRGBA(image.Rect(0, 0, dimX, dimY))

	n := Node{rect: image.Rect(0, 0, dimX, dimY)}

	var data []byte

	for i := range sprites {
		s := &sprites[i]
		node := n.insert(s)

		j, err := json.Marshal(s)
		if err != nil {
			log.Fatal(err)
		}
		data = append(data, j...)

		if node != nil {
			draw.Draw(img, node.rect, s.img, image.ZP, draw.Src)
		} else {
			log.Fatalf("could not place %s\n", s.Name)
		}

	}

	err = writeAtlas(outputName, img, data)
	if err != nil {
		log.Fatal(err)
	}
}

func parseDimensions(dim string) (dimX, dimY int, err error) {
	dims := strings.Split(dim, "x")
	if len(dims) != 2 {
		err = fmt.Errorf("couldn't parse dimension %s\n", dims)
		return
	}

	dimX, err = strconv.Atoi(dims[0])
	if err != nil {
		return
	}

	dimY, err = strconv.Atoi(dims[1])
	if err != nil {
		return
	}

	return
}

func readSprite(dir, name string, space int) (s sprite, err error) {
	path := path.Join(dir, name)
	reader, err := os.Open(path)
	if err != nil {
		return
	}
	defer reader.Close()

	img, _, err := image.Decode(reader)
	if err != nil {
		return
	}

	s.Name = strings.TrimSuffix(name, filepath.Ext(name))
	s.img = img
	rect := img.Bounds()
	s.Size = Size{rect.Dx() + space, rect.Dy() + space}
	s.area = s.Size.X * s.Size.Y
	return
}

func writeAtlas(name string, img *image.RGBA, data []byte) error {
	imageName := name + ".png"
	dataName := name + ".json"

	imageWriter, err := os.Create(imageName)
	if err != nil {
		return err
	}
	defer imageWriter.Close()

	dataWriter, err := os.Create(dataName)
	if err != nil {
		return err
	}
	defer dataWriter.Close()

	n, err := dataWriter.Write(data)
	if err != nil {
		return fmt.Errorf("position: %d error: %s", n, err)
	}

	err = png.Encode(imageWriter, img)
	if err != nil {
		return err
	}

	return nil
}
<commit_msg>Move atlas packing to its own function<commit_after>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"image"
	"image/draw"
	"image/png"
	"io/ioutil"
	"log"
	"os"
	"path"
	"path/filepath"
	"sort"
	"strconv"
	"strings"
)

func main() {
	var space int
	var dim string

	flag.IntVar(&space, "space", 1, "space added between images")
	flag.StringVar(&dim, "dimensions", "1024x1024", "atlas size")

	flag.Parse()

	args := flag.Args()

	inputDir := args[0]
	outputName := args[1]

	dimX, dimY, err := parseDimensions(dim)
	if err != nil {
		log.Fatal(err)
	}

	files, err := ioutil.ReadDir(inputDir)
	if err != nil {
		log.Fatal(err)
	}

	sprites := make([]sprite, len(files))

	totalArea := 0

	for i := range sprites {
		s, err := readSprite(inputDir, files[i].Name(), space)
		if err != nil {
			log.Fatal(err)
		}
		totalArea += s.area
		sprites[i] = s
	}

	if totalArea > dimX*dimY {
		log.Fatalf("%s atlas to small", dim)
	}

	// we want to place the largest sprite first
	sort.Sort(sort.Reverse(ByArea(sprites)))

	img, data := packAtlas(sprites, dimX, dimY)

	err = writeAtlas(outputName, img, data)
	if err != nil {
		log.Fatal(err)
	}
}

func parseDimensions(dim string) (dimX, dimY int, err error) {
	dims := strings.Split(dim, "x")
	if len(dims) != 2 {
		err = fmt.Errorf("couldn't parse dimension %s\n", dims)
		return
	}

	dimX, err = strconv.Atoi(dims[0])
	if err != nil {
		return
	}

	dimY, err = strconv.Atoi(dims[1])
	if err != nil {
		return
	}

	return
}

func readSprite(dir, name string, space int) (s sprite, err error) {
	path := path.Join(dir, name)
	reader, err := os.Open(path)
	if err != nil {
		return
	}
	defer reader.Close()

	img, _, err := image.Decode(reader)
	if err != nil {
		return
	}

	s.Name = strings.TrimSuffix(name, filepath.Ext(name))
	s.img = img
	rect := img.Bounds()
	s.Size = Size{rect.Dx() + space, rect.Dy() + space}
	s.area = s.Size.X * s.Size.Y
	return
}

func packAtlas(sprites []sprite, dimX, dimY int) (*image.RGBA, []byte) {
	img := image.NewRGBA(image.Rect(0, 0, dimX, dimY))

	n := Node{rect: image.Rect(0, 0, dimX, dimY)}

	var data []byte

	for i := range sprites {
		s := &sprites[i]
		node := n.insert(s)

		j, err := json.Marshal(s)
		if err != nil {
			log.Fatal(err)
		}
		data = append(data, j...)

		if node != nil {
			draw.Draw(img, node.rect, s.img, image.ZP, draw.Src)
		} else {
			log.Fatalf("could not place %s\n", s.Name)
		}

	}

	return img, data
}

func writeAtlas(name string, img *image.RGBA, data []byte) error {
	imageName := name + ".png"
	dataName := name + ".json"

	imageWriter, err := os.Create(imageName)
	if err != nil {
		return err
	}
	defer imageWriter.Close()

	dataWriter, err := os.Create(dataName)
	if err != nil {
		return err
	}
	defer dataWriter.Close()

	n, err := dataWriter.Write(data)
	if err != nil {
		return fmt.Errorf("position: %d error: %s", n, err)
	}

	err = png.Encode(imageWriter, img)
	if err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"strings"

	"github.com/drone/drone-go/drone"
	"github.com/drone/drone-go/plugin"
)

var (
	build             string
	buildDate         string
	sshKeyPath        string = "/root/.ssh"
	sshPrivateKeyPath string = path.Join(sshKeyPath, "id_rsa")
	sshPublicKeyPath  string = path.Join(sshKeyPath, "id_rsa.pub")
)

type DeployWorkspace struct {
  Workspace drone.Workspace
}

func main() {
	fmt.Printf("Drone Capistrano Plugin built at %s\n", buildDate)

	workspace := drone.Workspace{}
	repo := drone.Repo{}
	build := drone.Build{}
	vargs := Params{}

  dw := DeployWorkspace{workspace}

	plugin.Param("workspace", &workspace)
	plugin.Param("repo", &repo)
	plugin.Param("build", &build)
	plugin.Param("vargs", &vargs)
	plugin.MustParse()

	fmt.Printf("Installing your deploy key to %s\n", sshKeyPath)
	os.MkdirAll(sshKeyPath, 0700)
	ioutil.WriteFile(sshPrivateKeyPath, []byte(workspace.Keys.Private), 0600)
	ioutil.WriteFile(sshPublicKeyPath, []byte(workspace.Keys.Public), 0644)

  os.Setenv("BUILD_PATH", workspace.Path)
	os.Setenv("GIT_SSH_KEY", sshPrivateKeyPath)

	tasks := strings.Fields(vargs.Tasks)

	if len(tasks) == 0 {
		fmt.Println("Please provide Capistrano tasks to execute")
		os.Exit(1)
		return
	}

  bundle := dw.bundle("install", "--path", "build/bundle")
  if err := bundle.Run(); err != nil {
    fmt.Println(err)
    os.Exit(1)
    return
  }

  capistrano := dw.cap(tasks...)
	if err := capistrano.Run(); err != nil {
		fmt.Println(err)
		os.Exit(1)
		return
	}
}

func command(w drone.Workspace, cmd string, args ...string) *exec.Cmd {
	c := exec.Command(cmd, args...)
	c.Dir = w.Path
	c.Env = os.Environ()
	c.Stdout = os.Stdout
	c.Stderr = os.Stderr
	return c
}

func (w *DeployWorkspace) cap(tasks ...string) *exec.Cmd {
  args := append([]string{"exec", "cap"}, tasks...)
  return w.bundle(args...)
}

func (w *DeployWorkspace) bundle(args ...string) *exec.Cmd {
  return w.command("/bundle.sh", args...)
}

func (w *DeployWorkspace) command(cmd string, args ...string) *exec.Cmd {
  c := exec.Command(cmd, args...)
  c.Dir = w.Workspace.Path
  c.Env = os.Environ()
  c.Stdout = os.Stdout
  c.Stderr = os.Stderr
  return c
}
<commit_msg>running bundle install without path argument<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"strings"

	"github.com/drone/drone-go/drone"
	"github.com/drone/drone-go/plugin"
)

var (
	build             string
	buildDate         string
	sshKeyPath        string = "/root/.ssh"
	sshPrivateKeyPath string = path.Join(sshKeyPath, "id_rsa")
	sshPublicKeyPath  string = path.Join(sshKeyPath, "id_rsa.pub")
)

type DeployWorkspace struct {
  Workspace drone.Workspace
}

func main() {
	fmt.Printf("Drone Capistrano Plugin built at %s\n", buildDate)

	workspace := drone.Workspace{}
	repo := drone.Repo{}
	build := drone.Build{}
	vargs := Params{}

  dw := DeployWorkspace{workspace}

	plugin.Param("workspace", &workspace)
	plugin.Param("repo", &repo)
	plugin.Param("build", &build)
	plugin.Param("vargs", &vargs)
	plugin.MustParse()

	fmt.Printf("Installing your deploy key to %s\n", sshKeyPath)
	os.MkdirAll(sshKeyPath, 0700)
	ioutil.WriteFile(sshPrivateKeyPath, []byte(workspace.Keys.Private), 0600)
	ioutil.WriteFile(sshPublicKeyPath, []byte(workspace.Keys.Public), 0644)

  os.Setenv("BUILD_PATH", workspace.Path)
	os.Setenv("GIT_SSH_KEY", sshPrivateKeyPath)

	tasks := strings.Fields(vargs.Tasks)

	if len(tasks) == 0 {
		fmt.Println("Please provide Capistrano tasks to execute")
		os.Exit(1)
		return
	}

  bundle := dw.bundle("install")
  if err := bundle.Run(); err != nil {
    fmt.Println(err)
    os.Exit(1)
    return
  }

  capistrano := dw.cap(tasks...)
	if err := capistrano.Run(); err != nil {
		fmt.Println(err)
		os.Exit(1)
		return
	}
}

func command(w drone.Workspace, cmd string, args ...string) *exec.Cmd {
	c := exec.Command(cmd, args...)
	c.Dir = w.Path
	c.Env = os.Environ()
	c.Stdout = os.Stdout
	c.Stderr = os.Stderr
	return c
}

func (w *DeployWorkspace) cap(tasks ...string) *exec.Cmd {
  args := append([]string{"exec", "cap"}, tasks...)
  return w.bundle(args...)
}

func (w *DeployWorkspace) bundle(args ...string) *exec.Cmd {
  return w.command("/bundle.sh", args...)
}

func (w *DeployWorkspace) command(cmd string, args ...string) *exec.Cmd {
  c := exec.Command(cmd, args...)
  c.Dir = w.Workspace.Path
  c.Env = os.Environ()
  c.Stdout = os.Stdout
  c.Stderr = os.Stderr
  return c
}
<|endoftext|>


<commit_before>// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"os/signal"
	"time"

	"github.com/googlecloudplatform/gcsfuse/fs"
	"github.com/googlecloudplatform/gcsfuse/timeutil"
	"github.com/jacobsa/fuse"
	"github.com/jacobsa/fuse/fsutil"
	"github.com/jacobsa/gcloud/gcs"
	"github.com/jacobsa/gcloud/gcs/gcscaching"
	"golang.org/x/net/context"
)

func usage() {
	fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
	fmt.Fprintf(os.Stderr, "  %s [flags] <mount-point>\n", os.Args[0])
	flag.PrintDefaults()
}

var fBucketName = flag.String("bucket", "", "Name of GCS bucket to mount.")
var fReadOnly = flag.Bool("read_only", false, "Mount in read-only mode.")

var fTempDir = flag.String(
	"temp_dir", "",
	"The temporary directory in which to store local copies of GCS objects. "+
		"If empty, the system default (probably /tmp) will be used.")

var fTempDirLimit = flag.Int64(
	"temp_dir_bytes", 1<<31,
	"A desired limit on the number of bytes used in --temp_dir. May be exceeded "+
		"for dirty files that have not been flushed or closed.")

var fGCSChunkSize = flag.Uint64(
	"gcs_chunk_size", 1<<24,
	"If set to a non-zero value N, split up GCS objects into multiple chunks of "+
		"size at most N when reading, and do not read or cache unnecessary chunks.")

var fImplicitDirs = flag.Bool(
	"implicit_dirs",
	false,
	"Implicitly define directories based on their content. See "+
		"docs/semantics.md.")

var fSupportNlink = flag.Bool(
	"support_nlink",
	false,
	"Return meaningful values for nlink from fstat(2). See docs/semantics.md.")

var fStatCacheTTL = flag.String(
	"stat_cache_ttl",
	"1m",
	"If non-empty, a duration specifying how long to cache StatObject results "+
		"from GCS, e.g. \"2s\" or \"15ms\". See docs/semantics.md for more.")

var fTypeCacheTTL = flag.String(
	"type_cache_ttl",
	"1m",
	"If non-empty, a duration specifying how long to cache name -> file/dir "+
		"type mappings in directory inodes, e.g. \"2s\" or \"15ms\". "+
		"See docs/semantics.md.")

func getBucketName() string {
	s := *fBucketName
	if s == "" {
		fmt.Println("You must set --bucket.")
		os.Exit(1)
	}

	return s
}

func registerSIGINTHandler(mountPoint string) {
	// Register for SIGINT.
	signalChan := make(chan os.Signal, 1)
	signal.Notify(signalChan, os.Interrupt)

	// Start a goroutine that will unmount when the signal is received.
	go func() {
		for {
			<-signalChan
			log.Println("Received SIGINT, attempting to unmount...")

			err := fuse.Unmount(mountPoint)
			if err != nil {
				log.Printf("Failed to unmount in response to SIGINT: %v", err)
			} else {
				log.Printf("Successfully unmounted in response to SIGINT.")
				return
			}
		}
	}()
}

func getBucket() (b gcs.Bucket) {
	// Set up a GCS connection.
	log.Println("Initializing GCS connection.")
	conn, err := getConn()
	if err != nil {
		log.Fatal("Couldn't get GCS connection: ", err)
	}

	// Extract the appropriate bucket.
	b = conn.GetBucket(getBucketName())

	// Enable cached StatObject results, if appropriate.
	if *fStatCacheTTL != "" {
		ttl, err := time.ParseDuration(*fStatCacheTTL)
		if err != nil {
			log.Fatalf("Invalid --stat_cache_ttl: %v", err)
			return
		}

		const cacheCapacity = 4096
		b = gcscaching.NewFastStatBucket(
			ttl,
			gcscaching.NewStatCache(cacheCapacity),
			timeutil.RealClock(),
			b)
	}

	return
}

func main() {
	// Make logging output better.
	log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds)

	// Set up flags.
	flag.Usage = usage
	flag.Parse()

	// Grab the mount point.
	if flag.NArg() != 1 {
		usage()
		os.Exit(1)
	}

	mountPoint := flag.Arg(0)

	// Parse --type_cache_ttl
	var typeCacheTTL time.Duration
	if *fTypeCacheTTL != "" {
		var err error
		typeCacheTTL, err = time.ParseDuration(*fTypeCacheTTL)
		if err != nil {
			log.Fatalf("Invalid --type_cache_ttl: %v", err)
			return
		}
	}

	// Sanity check: make sure the temporary directory exists and is writable
	// currently. This gives a better user experience than harder to debug EIO
	// errors when reading files in the future.
	if *fTempDir != "" {
		f, err := fsutil.AnonymousFile(*fTempDir)
		f.Close()

		if err != nil {
			log.Fatalf(
				"Error writing to temporary directory (%q); are you sure it exists "+
					"with the correct permissions?",
				err.Error())
		}
	}

	// Create a file system server.
	bucket := getBucket()
	serverCfg := &fs.ServerConfig{
		Clock:               timeutil.RealClock(),
		Bucket:              bucket,
		TempDir:             *fTempDir,
		TempDirLimit:        *fTempDirLimit,
		GCSChunkSize:        *fGCSChunkSize,
		ImplicitDirectories: *fImplicitDirs,
		SupportNlink:        *fSupportNlink,
		DirTypeCacheTTL:     typeCacheTTL,
	}

	server, err := fs.NewServer(serverCfg)
	if err != nil {
		log.Fatal("fs.NewServer:", err)
	}

	// Mount the file system.
	mountCfg := &fuse.MountConfig{
		FSName:   bucket.Name(),
		ReadOnly: *fReadOnly,
	}

	mountedFS, err := fuse.Mount(mountPoint, server, mountCfg)
	if err != nil {
		log.Fatal("Mount:", err)
	}

	log.Println("File system has been successfully mounted.")

	// Let the user unmount with Ctrl-C (SIGINT).
	registerSIGINTHandler(mountedFS.Dir())

	// Wait for it to be unmounted.
	if err := mountedFS.Join(context.Background()); err != nil {
		log.Fatal("MountedFileSystem.Join:", err)
	}

	log.Println("Successfully exiting.")
}
<commit_msg>Updated main.go.<commit_after>// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"os/signal"
	"time"

	"github.com/googlecloudplatform/gcsfuse/fs"
	"github.com/googlecloudplatform/gcsfuse/timeutil"
	"github.com/jacobsa/fuse"
	"github.com/jacobsa/fuse/fsutil"
	"github.com/jacobsa/gcloud/gcs"
	"github.com/jacobsa/gcloud/gcs/gcscaching"
	"golang.org/x/net/context"
)

func usage() {
	fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
	fmt.Fprintf(os.Stderr, "  %s [flags] <mount-point>\n", os.Args[0])
	flag.PrintDefaults()
}

var fBucketName = flag.String("bucket", "", "Name of GCS bucket to mount.")
var fMountPoint = flag.String("mount_point", "", "File system location.")
var fReadOnly = flag.Bool("read_only", false, "Mount in read-only mode.")

var fTempDir = flag.String(
	"temp_dir", "",
	"The temporary directory in which to store local copies of GCS objects. "+
		"If empty, the system default (probably /tmp) will be used.")

var fTempDirLimit = flag.Int64(
	"temp_dir_bytes", 1<<31,
	"A desired limit on the number of bytes used in --temp_dir. May be exceeded "+
		"for dirty files that have not been flushed or closed.")

var fGCSChunkSize = flag.Uint64(
	"gcs_chunk_size", 1<<24,
	"If set to a non-zero value N, split up GCS objects into multiple chunks of "+
		"size at most N when reading, and do not read or cache unnecessary chunks.")

var fImplicitDirs = flag.Bool(
	"implicit_dirs",
	false,
	"Implicitly define directories based on their content. See "+
		"docs/semantics.md.")

var fSupportNlink = flag.Bool(
	"support_nlink",
	false,
	"Return meaningful values for nlink from fstat(2). See docs/semantics.md.")

var fStatCacheTTL = flag.String(
	"stat_cache_ttl",
	"1m",
	"If non-empty, a duration specifying how long to cache StatObject results "+
		"from GCS, e.g. \"2s\" or \"15ms\". See docs/semantics.md for more.")

var fTypeCacheTTL = flag.String(
	"type_cache_ttl",
	"1m",
	"If non-empty, a duration specifying how long to cache name -> file/dir "+
		"type mappings in directory inodes, e.g. \"2s\" or \"15ms\". "+
		"See docs/semantics.md.")

func getBucketName() string {
	s := *fBucketName
	if s == "" {
		fmt.Println("You must set --bucket.")
		os.Exit(1)
	}

	return s
}

func registerSIGINTHandler(mountPoint string) {
	// Register for SIGINT.
	signalChan := make(chan os.Signal, 1)
	signal.Notify(signalChan, os.Interrupt)

	// Start a goroutine that will unmount when the signal is received.
	go func() {
		for {
			<-signalChan
			log.Println("Received SIGINT, attempting to unmount...")

			err := fuse.Unmount(mountPoint)
			if err != nil {
				log.Printf("Failed to unmount in response to SIGINT: %v", err)
			} else {
				log.Printf("Successfully unmounted in response to SIGINT.")
				return
			}
		}
	}()
}

func getBucket() (b gcs.Bucket) {
	// Set up a GCS connection.
	log.Println("Initializing GCS connection.")
	conn, err := getConn()
	if err != nil {
		log.Fatal("Couldn't get GCS connection: ", err)
	}

	// Extract the appropriate bucket.
	b = conn.GetBucket(getBucketName())

	// Enable cached StatObject results, if appropriate.
	if *fStatCacheTTL != "" {
		ttl, err := time.ParseDuration(*fStatCacheTTL)
		if err != nil {
			log.Fatalf("Invalid --stat_cache_ttl: %v", err)
			return
		}

		const cacheCapacity = 4096
		b = gcscaching.NewFastStatBucket(
			ttl,
			gcscaching.NewStatCache(cacheCapacity),
			timeutil.RealClock(),
			b)
	}

	return
}

func main() {
	// Make logging output better.
	log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds)

	// Set up flags.
	flag.Usage = usage
	flag.Parse()

	// Check --mount_point.
	if *fMountPoint == "" {
		log.Fatalf("You must set --mount_point.")
	}

	mountPoint := *fMountPoint

	// Parse --type_cache_ttl
	var typeCacheTTL time.Duration
	if *fTypeCacheTTL != "" {
		var err error
		typeCacheTTL, err = time.ParseDuration(*fTypeCacheTTL)
		if err != nil {
			log.Fatalf("Invalid --type_cache_ttl: %v", err)
			return
		}
	}

	// Sanity check: make sure the temporary directory exists and is writable
	// currently. This gives a better user experience than harder to debug EIO
	// errors when reading files in the future.
	if *fTempDir != "" {
		f, err := fsutil.AnonymousFile(*fTempDir)
		f.Close()

		if err != nil {
			log.Fatalf(
				"Error writing to temporary directory (%q); are you sure it exists "+
					"with the correct permissions?",
				err.Error())
		}
	}

	// Create a file system server.
	bucket := getBucket()
	serverCfg := &fs.ServerConfig{
		Clock:               timeutil.RealClock(),
		Bucket:              bucket,
		TempDir:             *fTempDir,
		TempDirLimit:        *fTempDirLimit,
		GCSChunkSize:        *fGCSChunkSize,
		ImplicitDirectories: *fImplicitDirs,
		SupportNlink:        *fSupportNlink,
		DirTypeCacheTTL:     typeCacheTTL,
	}

	server, err := fs.NewServer(serverCfg)
	if err != nil {
		log.Fatal("fs.NewServer:", err)
	}

	// Mount the file system.
	mountCfg := &fuse.MountConfig{
		FSName:   bucket.Name(),
		ReadOnly: *fReadOnly,
	}

	mountedFS, err := fuse.Mount(mountPoint, server, mountCfg)
	if err != nil {
		log.Fatal("Mount:", err)
	}

	log.Println("File system has been successfully mounted.")

	// Let the user unmount with Ctrl-C (SIGINT).
	registerSIGINTHandler(mountedFS.Dir())

	// Wait for it to be unmounted.
	if err := mountedFS.Join(context.Background()); err != nil {
		log.Fatal("MountedFileSystem.Join:", err)
	}

	log.Println("Successfully exiting.")
}
<|endoftext|>


<commit_before>package main

import "fmt"

func main() {
	fmt.Println("hello mongo")
}
<commit_msg>simple mqtt client with mongo<commit_after>package main

import (
	"fmt"
	"os"
	"runtime"
	"time"

	"labix.org/v2/mgo"

	MQTT "git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git"
)

type Sensor struct {
	holder []byte
	id     byte
	prefix byte
	code   byte
}

var session = new(mgo.Session)
var collection *mgo.Collection

func mgoSessionFinalizer(session *mgo.Session) {
	session.Close()
}

func init() {
	runtime.SetFinalizer(session, mgoSessionFinalizer)
	var err error
	//TODO: obtain MongoDB details from configuration
	session, err = mgo.Dial("db.skydome.io:27017")
	if err != nil {
		panic(err)
	}

	session.SetMode(mgo.Monotonic, true)
	collection = session.DB("sensors").C("raw")
}

var f MQTT.MessageHandler = func(client *MQTT.MqttClient, msg MQTT.Message) {
	//fmt.Printf("TOPIC: %s\n", msg.Topic())
	fmt.Println("Size of array : ", len(msg.Payload()))
	fmt.Println("MSG: ", msg.Payload())

	sensor := Sensor{msg.Payload()[:6], msg.Payload()[6], msg.Payload()[7], msg.Payload()[8]}
	fmt.Println("sensor : ", sensor)
	collection.Insert(sensor)
}

func main() {
	opts := MQTT.NewClientOptions().SetBroker("tcp://107.170.134.171:1883").SetClientId("trivial")
	opts.SetTraceLevel(MQTT.Off)
	opts.SetDefaultPublishHandler(f)

	c := MQTT.NewClient(opts)
	_, err := c.Start()
	if err != nil {
		panic(err)
	}

	filter, _ := MQTT.NewTopicFilter("skydome", 0)
	if receipt, err := c.StartSubscription(nil, filter); err != nil {
		fmt.Println(err)
		os.Exit(1)
	} else {
		<-receipt
	}

	for {
		time.Sleep(1 * time.Second)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"

	"github.com/cl0ne/go-checkers/checkers"
	"github.com/fatih/color"
)

var bg = color.New(color.BgBlack, color.FgHiWhite).SprintFunc()
var empty = color.New(color.FgBlack, color.BgHiWhite).SprintFunc()

var checker = map[bool]map[bool]string{
	false: {false: "▪ ", true: "◈ "},
	true:  {false: "▫ ", true: "◇ "},
	// another style:
	// false: {false: "⛂ ", true: "⛃ "},
	// true:  {false: "⛀ ", true: "⛁ "},
}

func drawBoard(b *checkers.Board) {
	var header = "a b c d e f g h i j k l m n o p q r s t u v w x y z "
	fmt.Print()
	fmt.Println(" ", header[0:b.Size()*2])
	for r := b.Size(); r > 0; r-- {
		fmt.Print(r, " ")
		for c := 0; c < b.Size(); c++ {
			if b.IsWhiteSquare(checkers.Point{c, r - 1}) {
				fmt.Print(bg("  "))
			} else {
				ch := b.GetChecker(c, r-1)
				if ch == nil {
					fmt.Print(empty("  "))
				} else {
					fmt.Print(empty(checker[ch.IsWhite()][ch.IsQueen()]))
				}
			}
		}
		fmt.Println()
	}
	fmt.Println()
}

type PlayerInput struct {
	name string
}

func (i PlayerInput) SelectChecker(availableCheckers []*checkers.Checker) int {
	var header = "abcdefghijklmnopqrstuvwxyz"
	fmt.Printf("%s, take a checker:\n", i.name)
	for i := range availableCheckers {
		var posX = availableCheckers[i].Position().X
		var posY = availableCheckers[i].Position().Y
		if availableCheckers[i].IsWhite() {
			if availableCheckers[i].IsQueen() {
				fmt.Printf("%d. White queen on %c%d\n", i+1, header[posX], posY+1)
			} else {
				fmt.Printf("%d. White on %c%d\n", i+1, header[posX], posY+1)
			}
		} else {
			if availableCheckers[i].IsQueen() {
				fmt.Printf("%d. %s queen on %c%d\n", i+1, empty("Black"), header[posX], posY+1)
			} else {
				fmt.Printf("%d. %s on %c%d\n", i+1, empty("Black"), header[posX], posY+1)
			}
		}
	}
	var checkerNumber int
	fmt.Scanln(&checkerNumber)
	return checkerNumber - 1
}

func (i PlayerInput) SelectTargetPos(availableMoves []checkers.Move) int {
	var header = "abcdefghijklmnopqrstuvwxyz"
	fmt.Printf("%s, where would you go?\n", i.name)
	for i := range availableMoves {
		var posX = availableMoves[i].Target.X
		var posY = availableMoves[i].Target.Y
		fmt.Printf("%d. To %c%d\n", i+1, header[posX], posY+1)
	}
	var targetNumber int
	fmt.Scanln(&targetNumber)
	return targetNumber - 1
}

func main() {
	inputs := []checkers.PlayerPoller{
		&PlayerInput{"White"},
		&PlayerInput{"Black"},
	}
	g := checkers.NewGame(inputs[0], inputs[1])
	g.Start()

	drawBoard(g.GetBoard())
	for !g.IsFinished() {
		if g.IsWhitesMove() {
			fmt.Println("White moves:")
		} else {
			fmt.Println(empty("Black"), "moves:")
		}
		g.Update()
		drawBoard(g.GetBoard())
		fmt.Println()
	}
	if g.IsBlackWin() {
		fmt.Println(empty("Black"), "wins")
	} else {
		fmt.Println("White wins")
	}
}
<commit_msg>Add checking of indexes Resolve cl0ne/go-checkers#4<commit_after>package main

import (
	"fmt"

	"github.com/cl0ne/go-checkers/checkers"
	"github.com/fatih/color"
)

var bg = color.New(color.BgBlack, color.FgHiWhite).SprintFunc()
var empty = color.New(color.FgBlack, color.BgHiWhite).SprintFunc()

var checker = map[bool]map[bool]string{
	false: {false: "▪ ", true: "◈ "},
	true:  {false: "▫ ", true: "◇ "},
	// another style:
	// false: {false: "⛂ ", true: "⛃ "},
	// true:  {false: "⛀ ", true: "⛁ "},
}

func drawBoard(b *checkers.Board) {
	var header = "a b c d e f g h i j k l m n o p q r s t u v w x y z "
	fmt.Print()
	fmt.Println(" ", header[0:b.Size()*2])
	for r := b.Size(); r > 0; r-- {
		fmt.Print(r, " ")
		for c := 0; c < b.Size(); c++ {
			if b.IsWhiteSquare(checkers.Point{c, r - 1}) {
				fmt.Print(bg("  "))
			} else {
				ch := b.GetChecker(c, r-1)
				if ch == nil {
					fmt.Print(empty("  "))
				} else {
					fmt.Print(empty(checker[ch.IsWhite()][ch.IsQueen()]))
				}
			}
		}
		fmt.Println()
	}
	fmt.Println()
}

type PlayerInput struct {
	name string
}

func (i PlayerInput) SelectChecker(availableCheckers []*checkers.Checker) int {
	var header = "abcdefghijklmnopqrstuvwxyz"
	for {
		fmt.Printf("%s, take a checker:\n", i.name)
		for i := range availableCheckers {
			var posX = availableCheckers[i].Position().X
			var posY = availableCheckers[i].Position().Y
			if availableCheckers[i].IsWhite() {
				if availableCheckers[i].IsQueen() {
					fmt.Printf("%d. White queen on %c%d\n", i+1, header[posX], posY+1)
				} else {
					fmt.Printf("%d. White on %c%d\n", i+1, header[posX], posY+1)
				}
			} else {
				if availableCheckers[i].IsQueen() {
					fmt.Printf("%d. %s queen on %c%d\n", i+1, empty("Black"), header[posX], posY+1)
				} else {
					fmt.Printf("%d. %s on %c%d\n", i+1, empty("Black"), header[posX], posY+1)
				}
			}
		}
		var checkerNumber int
		_, ok := fmt.Scanln(&checkerNumber)
		if ok == nil && (checkerNumber-1) >= 0 && (checkerNumber-1) < len(availableCheckers) {
			return checkerNumber - 1
		} else {
			if ok != nil {
				var discard string
				fmt.Scanln(&discard)
			}
			fmt.Printf("Nope, dude. This variant doesn't exist! Pick another\n")
			continue
		}
	}
}

func (i PlayerInput) SelectTargetPos(availableMoves []checkers.Move) int {
	var header = "abcdefghijklmnopqrstuvwxyz"
	for {
		fmt.Printf("%s, where would you go?\n", i.name)
		for i := range availableMoves {
			var posX = availableMoves[i].Target.X
			var posY = availableMoves[i].Target.Y
			fmt.Printf("%d. To %c%d\n", i+1, header[posX], posY+1)
		}
		var targetNumber int
		_, ok := fmt.Scanln(&targetNumber)
		if ok == nil && (targetNumber-1) >= 0 && (targetNumber-1) < len(availableMoves) {
			return targetNumber - 1
		} else {
			if ok != nil {
				var discard string
				fmt.Scanln(&discard)
			}
			fmt.Printf("Nope, dude. This variant doesn't exist! Pick another\n")
			continue
		}
	}
}

func main() {
	inputs := []checkers.PlayerPoller{
		&PlayerInput{"White"},
		&PlayerInput{"Black"},
	}
	g := checkers.NewGame(inputs[0], inputs[1])
	g.Start()

	drawBoard(g.GetBoard())
	for !g.IsFinished() {
		if g.IsWhitesMove() {
			fmt.Println("White moves:")
		} else {
			fmt.Println(empty("Black"), "moves:")
		}
		g.Update()
		drawBoard(g.GetBoard())
		fmt.Println()
	}
	if g.IsBlackWin() {
		fmt.Println(empty("Black"), "wins")
	} else {
		fmt.Println("White wins")
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"os/signal"
	"regexp"
	"runtime"
	"strconv"
	"strings"
	"syscall"
	"time"

	"github.com/mackerelio/mackerel-agent/command"
	"github.com/mackerelio/mackerel-agent/config"
	"github.com/mackerelio/mackerel-agent/logging"
	"github.com/mackerelio/mackerel-agent/version"
)

// allow options like -role=... -role=...
type roleFullnamesFlag []string

var roleFullnamePattern = regexp.MustCompile(`^[a-zA-Z0-9][-_a-zA-Z0-9]*:\s*[a-zA-Z0-9][-_a-zA-Z0-9]*$`)

func (r *roleFullnamesFlag) String() string {
	return fmt.Sprint(*r)
}

func (r *roleFullnamesFlag) Set(input string) error {
	inputRoles := strings.Split(input, ",")
	*r = append(*r, inputRoles...)
	return nil
}

type otherOptions struct {
	printVersion bool
	runOnce      bool
}

var logger = logging.GetLogger("main")

func main() {
	conf, otherOptions := resolveConfig()

	if otherOptions != nil && otherOptions.printVersion {
		fmt.Printf("mackerel-agent version %s (rev %s) [%s %s %s] \n",
			version.VERSION, version.GITCOMMIT, runtime.GOOS, runtime.GOARCH, runtime.Version())
		exitWithoutPidfileCleaning(0)
	}

	if conf.Verbose {
		logging.SetLogLevel(logging.DEBUG)
	}

	logger.Infof("Starting mackerel-agent version:%s, rev:%s, apibase:%s", version.VERSION, version.GITCOMMIT, conf.Apibase)

	if otherOptions != nil && otherOptions.runOnce {
		command.RunOnce(conf)
		exitWithoutPidfileCleaning(0)
	}

	if conf.Apikey == "" {
		logger.Criticalf("Apikey must be specified in the command-line flag or in the config file")
		exit(1, conf)
	}

	if err := start(conf); err != nil {
		exit(1, conf)
	}
}

// resolveConfig parses command line arguments and loads config file to
// return config.Config information.
// As a special case, if `-version` flag is given it stops processing
// and return true for the second return value.
func resolveConfig() (*config.Config, *otherOptions) {
	conf := &config.Config{}
	otherOptions := &otherOptions{}

	var (
		conffile     = flag.String("conf", config.DefaultConfig.Conffile, "Config file path (Configs in this file are over-written by command line options)")
		apibase      = flag.String("apibase", config.DefaultConfig.Apibase, "API base")
		pidfile      = flag.String("pidfile", config.DefaultConfig.Pidfile, "File containing PID")
		root         = flag.String("root", config.DefaultConfig.Root, "Directory containing variable state information")
		apikey       = flag.String("apikey", "", "API key from mackerel.io web site")
		diagnostic   = flag.Bool("diagnostic", false, "Enables diagnostic features")
		runOnce      = flag.Bool("once", false, "Show spec and metrics to stdout once")
		printVersion = flag.Bool("version", false, "Prints version and exit")
	)

	var verbose bool
	flag.BoolVar(&verbose, "verbose", config.DefaultConfig.Verbose, "Toggle verbosity")
	flag.BoolVar(&verbose, "v", config.DefaultConfig.Verbose, "Toggle verbosity (shorthand)")

	// The value of "role" option is internally "roll fullname",
	// but we call it "role" here for ease.
	var roleFullnames roleFullnamesFlag
	flag.Var(&roleFullnames, "role", "Set this host's roles (format: <service>:<role>)")

	flag.Parse()

	if *printVersion {
		otherOptions.printVersion = true
		return conf, otherOptions
	}

	if *runOnce {
		otherOptions.runOnce = true
		return conf, otherOptions
	}

	conf, confErr := config.LoadConfig(*conffile)
	if confErr != nil {
		logger.Criticalf("Failed to load the config file: %s", confErr)
		exitWithoutPidfileCleaning(1)
	}

	// overwrite config from file by config from args
	flag.Visit(func(f *flag.Flag) {
		switch f.Name {
		case "apibase":
			conf.Apibase = *apibase
		case "apikey":
			conf.Apikey = *apikey
		case "pidfile":
			conf.Pidfile = *pidfile
		case "root":
			conf.Root = *root
		case "diagnostic":
			conf.Diagnostic = *diagnostic
		case "verbose", "v":
			conf.Verbose = verbose
		case "role":
			conf.Roles = roleFullnames
		}
	})

	r := []string{}
	for _, roleFullName := range conf.Roles {
		if !roleFullnamePattern.MatchString(roleFullName) {
			logger.Errorf("Bad format for role fullname (expecting <service>:<role>. Alphabet, numbers, hyphens and underscores are acceptable, but the first character must not be a hyphen or an underscore.): '%s'", roleFullName)
		} else {
			r = append(r, roleFullName)
		}
	}
	conf.Roles = r
	return conf, nil
}

func createPidFile(pidfile string) error {
	if pidString, err := ioutil.ReadFile(pidfile); err == nil {
		if pid, err := strconv.Atoi(string(pidString)); err == nil {
			if existsPid(pid) {
				return fmt.Errorf("Pidfile found, try stopping another running mackerel-agent or delete %s", pidfile)
			}
			// Note mackerel-agent in windows can't remove pidfile during stoping the service
			logger.Warningf("Pidfile found, but there seems no another process of mackerel-agent. Ignoring %s", pidfile)
		} else {
			logger.Warningf("Malformed pidfile found. Ignoring %s", pidfile)
		}
	}

	file, err := os.Create(pidfile)
	if err != nil {
		logger.Criticalf("Failed to create a pidfile: %s", err)
		return err
	}
	defer file.Close()

	_, err = fmt.Fprintf(file, "%d", os.Getpid())
	return err
}

func removePidFile(pidfile string) {
	if err := os.Remove(pidfile); err != nil {
		logger.Errorf("Failed to remove the pidfile: %s: %s", pidfile, err)
	}
}

func exit(exitCode int, conf *config.Config) {
	removePidFile(conf.Pidfile)
	exitWithoutPidfileCleaning(exitCode)
}

func exitWithoutPidfileCleaning(exitCode int) {
	os.Exit(exitCode)
}

func start(conf *config.Config) error {
	if err := createPidFile(conf.Pidfile); err != nil {
		return err
	}

	ctx, err := command.Prepare(conf)
	if err != nil {
		logger.Criticalf(err.Error())
		exit(1, conf)
	}

	termCh := make(chan struct{})
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
	go signalHandler(c, ctx, termCh)

	exitCode := command.Run(ctx, termCh)
	exit(exitCode, conf)

	return nil
}

var maxTerminatingInterval = 30 * time.Second

func signalHandler(c chan os.Signal, ctx *command.Context, termCh chan struct{}) {
	received := false
	for sig := range c {
		if sig == syscall.SIGHUP {
			logger.Debugf("Received signal '%v'", sig)
			// TODO reload configuration file

			ctx.UpdateHostSpecs()
		} else {
			if !received {
				received = true
				logger.Infof(
					"Received signal '%v', try graceful shutdown up to %f seconds. If you want force shutdown immediately, send a signal again.",
					sig,
					maxTerminatingInterval.Seconds())
			} else {
				logger.Infof("Received signal '%v' again, force shutdown.", sig)
			}
			termCh <- struct{}{}
			go func() {
				time.Sleep(maxTerminatingInterval)
				logger.Infof("Timed out. force shutdown.")
				termCh <- struct{}{}
			}()
		}
	}
}
<commit_msg>fix exit way<commit_after>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"os/signal"
	"regexp"
	"runtime"
	"strconv"
	"strings"
	"syscall"
	"time"

	"github.com/mackerelio/mackerel-agent/command"
	"github.com/mackerelio/mackerel-agent/config"
	"github.com/mackerelio/mackerel-agent/logging"
	"github.com/mackerelio/mackerel-agent/version"
)

// allow options like -role=... -role=...
type roleFullnamesFlag []string

var roleFullnamePattern = regexp.MustCompile(`^[a-zA-Z0-9][-_a-zA-Z0-9]*:\s*[a-zA-Z0-9][-_a-zA-Z0-9]*$`)

func (r *roleFullnamesFlag) String() string {
	return fmt.Sprint(*r)
}

func (r *roleFullnamesFlag) Set(input string) error {
	inputRoles := strings.Split(input, ",")
	*r = append(*r, inputRoles...)
	return nil
}

type otherOptions struct {
	printVersion bool
	runOnce      bool
}

var logger = logging.GetLogger("main")

func main() {
	conf, otherOptions := resolveConfig()

	if otherOptions != nil && otherOptions.printVersion {
		fmt.Printf("mackerel-agent version %s (rev %s) [%s %s %s] \n",
			version.VERSION, version.GITCOMMIT, runtime.GOOS, runtime.GOARCH, runtime.Version())
		exit(0)
	}

	if conf.Verbose {
		logging.SetLogLevel(logging.DEBUG)
	}

	logger.Infof("Starting mackerel-agent version:%s, rev:%s, apibase:%s", version.VERSION, version.GITCOMMIT, conf.Apibase)

	if otherOptions != nil && otherOptions.runOnce {
		command.RunOnce(conf)
		exit(0)
	}

	if conf.Apikey == "" {
		logger.Criticalf("Apikey must be specified in the command-line flag or in the config file")
		exit(1)
	}

	if err := start(conf); err != nil {
		exit(1)
	}
}

// resolveConfig parses command line arguments and loads config file to
// return config.Config information.
// As a special case, if `-version` flag is given it stops processing
// and return true for the second return value.
func resolveConfig() (*config.Config, *otherOptions) {
	conf := &config.Config{}
	otherOptions := &otherOptions{}

	var (
		conffile     = flag.String("conf", config.DefaultConfig.Conffile, "Config file path (Configs in this file are over-written by command line options)")
		apibase      = flag.String("apibase", config.DefaultConfig.Apibase, "API base")
		pidfile      = flag.String("pidfile", config.DefaultConfig.Pidfile, "File containing PID")
		root         = flag.String("root", config.DefaultConfig.Root, "Directory containing variable state information")
		apikey       = flag.String("apikey", "", "API key from mackerel.io web site")
		diagnostic   = flag.Bool("diagnostic", false, "Enables diagnostic features")
		runOnce      = flag.Bool("once", false, "Show spec and metrics to stdout once")
		printVersion = flag.Bool("version", false, "Prints version and exit")
	)

	var verbose bool
	flag.BoolVar(&verbose, "verbose", config.DefaultConfig.Verbose, "Toggle verbosity")
	flag.BoolVar(&verbose, "v", config.DefaultConfig.Verbose, "Toggle verbosity (shorthand)")

	// The value of "role" option is internally "roll fullname",
	// but we call it "role" here for ease.
	var roleFullnames roleFullnamesFlag
	flag.Var(&roleFullnames, "role", "Set this host's roles (format: <service>:<role>)")

	flag.Parse()

	if *printVersion {
		otherOptions.printVersion = true
		return conf, otherOptions
	}

	if *runOnce {
		otherOptions.runOnce = true
		return conf, otherOptions
	}

	conf, confErr := config.LoadConfig(*conffile)
	if confErr != nil {
		logger.Criticalf("Failed to load the config file: %s", confErr)
		exit(1)
	}

	// overwrite config from file by config from args
	flag.Visit(func(f *flag.Flag) {
		switch f.Name {
		case "apibase":
			conf.Apibase = *apibase
		case "apikey":
			conf.Apikey = *apikey
		case "pidfile":
			conf.Pidfile = *pidfile
		case "root":
			conf.Root = *root
		case "diagnostic":
			conf.Diagnostic = *diagnostic
		case "verbose", "v":
			conf.Verbose = verbose
		case "role":
			conf.Roles = roleFullnames
		}
	})

	r := []string{}
	for _, roleFullName := range conf.Roles {
		if !roleFullnamePattern.MatchString(roleFullName) {
			logger.Errorf("Bad format for role fullname (expecting <service>:<role>. Alphabet, numbers, hyphens and underscores are acceptable, but the first character must not be a hyphen or an underscore.): '%s'", roleFullName)
		} else {
			r = append(r, roleFullName)
		}
	}
	conf.Roles = r
	return conf, nil
}

func createPidFile(pidfile string) error {
	if pidString, err := ioutil.ReadFile(pidfile); err == nil {
		if pid, err := strconv.Atoi(string(pidString)); err == nil {
			if existsPid(pid) {
				return fmt.Errorf("Pidfile found, try stopping another running mackerel-agent or delete %s", pidfile)
			}
			// Note mackerel-agent in windows can't remove pidfile during stoping the service
			logger.Warningf("Pidfile found, but there seems no another process of mackerel-agent. Ignoring %s", pidfile)
		} else {
			logger.Warningf("Malformed pidfile found. Ignoring %s", pidfile)
		}
	}

	file, err := os.Create(pidfile)
	if err != nil {
		logger.Criticalf("Failed to create a pidfile: %s", err)
		return err
	}
	defer file.Close()

	_, err = fmt.Fprintf(file, "%d", os.Getpid())
	return err
}

func removePidFile(pidfile string) {
	if err := os.Remove(pidfile); err != nil {
		logger.Errorf("Failed to remove the pidfile: %s: %s", pidfile, err)
	}
}

func exit(exitCode int) {
	os.Exit(exitCode)
}

func start(conf *config.Config) error {
	if err := createPidFile(conf.Pidfile); err != nil {
		return err
	}
	defer removePidFile(conf.Pidfile)

	ctx, err := command.Prepare(conf)
	if err != nil {
		logger.Criticalf(err.Error())
		exit(1)
	}

	termCh := make(chan struct{})
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
	go signalHandler(c, ctx, termCh)

	exitCode := command.Run(ctx, termCh)
	exit(exitCode)

	return nil
}

var maxTerminatingInterval = 30 * time.Second

func signalHandler(c chan os.Signal, ctx *command.Context, termCh chan struct{}) {
	received := false
	for sig := range c {
		if sig == syscall.SIGHUP {
			logger.Debugf("Received signal '%v'", sig)
			// TODO reload configuration file

			ctx.UpdateHostSpecs()
		} else {
			if !received {
				received = true
				logger.Infof(
					"Received signal '%v', try graceful shutdown up to %f seconds. If you want force shutdown immediately, send a signal again.",
					sig,
					maxTerminatingInterval.Seconds())
			} else {
				logger.Infof("Received signal '%v' again, force shutdown.", sig)
			}
			termCh <- struct{}{}
			go func() {
				time.Sleep(maxTerminatingInterval)
				logger.Infof("Timed out. force shutdown.")
				termCh <- struct{}{}
			}()
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/sha1"
	"database/sql"
	"encoding/base64"
	"encoding/json"
	"encoding/xml"
	"fmt"
	"html"
	"html/template"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"time"

	"github.com/dchest/uniuri"
	"github.com/ewhal/pygments"
	_ "github.com/go-sql-driver/mysql"
	"github.com/gorilla/mux"
)

const (
	ADDRESS  = "http://localhost:9900"
	LENGTH   = 6
	PORT     = ":9900"
	USERNAME = ""
	PASS     = ""
	NAME     = ""
	DATABASE = USERNAME + ":" + PASS + "@/" + NAME + "?charset=utf8"
)

type Response struct {
	ID     string `json:"id"`
	TITLE  string `json:"title"`
	HASH   string `json:"hash"`
	URL    string `json:"url"`
	SIZE   int    `json:"size"`
	DELKEY string `json:"delkey"`
}

type Page struct {
	Title    string
	Body     []byte
	Raw      string
	Home     string
	Download string
	Clone    string
}

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

func generateName() string {
	s := uniuri.NewLen(LENGTH)
	db, err := sql.Open("mysql", DATABASE)
	check(err)

	query, err := db.Query("select id from pastebin")
	for query.Next() {
		var id string
		err := query.Scan(&id)
		if err != nil {

		}
		if id == s {
			generateName()
		}
	}
	db.Close()

	return s

}
func hash(paste string) string {
	hasher := sha1.New()

	hasher.Write([]byte(paste))
	sha := base64.URLEncoding.EncodeToString(hasher.Sum(nil))
	return sha
}

func save(raw string, lang string, title string, expiry string) []string {
	db, err := sql.Open("mysql", DATABASE)
	check(err)

	sha := hash(raw)
	query, err := db.Query("select id, title, hash, data, delkey from pastebin")
	for query.Next() {
		var id, title, hash, paste, delkey string
		err := query.Scan(&id, &title, &hash, &paste, &delkey)
		check(err)
		if hash == sha {
			url := ADDRESS + "/p/" + id
			return []string{id, title, hash, url, paste, delkey}
		}
	}
	id := generateName()
	var url string
	if lang == "" {
		url = ADDRESS + "/p/" + id
	} else {
		url = ADDRESS + "/p/" + id + "/" + lang
	}
	now := time.Now()
	var expiryTime string

	switch expiry {
	case "5 minutes":
		expiryTime = now.Add(time.Minute * 5).Format(time.RFC3339)
		break

	case "1 hour":
		expiryTime = now.Add(time.Hour + 1).Format(time.RFC3339)
		break

	case "1 day":
		expiryTime = now.Add(time.Hour * 24 * 1).Format(time.RFC3339)
		break

	case "1 week":
		expiryTime = now.Add(time.Hour * 24 * 7).Format(time.RFC3339)
		break

	case "1 month":
		expiryTime = now.Add(time.Hour * 24 * 30).Format(time.RFC3339)
		break

	case "1 year":
		expiryTime = now.Add(time.Hour * 24 * 365).Format(time.RFC3339)
		break

	default:
		expiryTime = now.Format(time.RFC3339)
		break

	}
	delKey := uniuri.NewLen(40)
	paste := html.EscapeString(raw)

	stmt, err := db.Prepare("INSERT INTO pastebin(id, title, hash, data, delkey, expiry) values(?,?,?,?,?,?)")
	check(err)
	if title == "" {
		_, err = stmt.Exec(id, id, sha, paste, delKey, expiryTime)
		check(err)
	} else {
		_, err = stmt.Exec(id, html.EscapeString(title), sha, paste, delKey, expiryTime)
		check(err)
	}
	db.Close()
	return []string{id, title, sha, url, paste, delKey}
}

func delHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	delkey := vars["delKey"]

	db, err := sql.Open("mysql", DATABASE)
	check(err)

	stmt, err := db.Prepare("delete from pastebin where delkey=?")
	check(err)

	res, err := stmt.Exec(html.EscapeString(delkey))
	check(err)

	_, err = res.RowsAffected()
	if err == sql.ErrNoRows {
		io.WriteString(w, "Error invalid paste")
	} else {
		io.WriteString(w, paste+" deleted")
	}
	db.Close()

}
func saveHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	output := vars["output"]
	switch r.Method {
	case "POST":
		paste := r.FormValue("p")
		lang := r.FormValue("lang")
		title := r.FormValue("title")
		expiry := r.FormValue("expiry")
		if paste == "" {
			http.Error(w, "Empty paste", 500)
			return
		}
		values := save(paste, lang, title, expiry)
		b := &Response{
			ID:     values[0],
			TITLE:  values[1],
			HASH:   values[2],
			URL:    values[3],
			SIZE:   len(values[4]),
			DELKEY: values[5],
		}

		switch output {
		case "json":

			w.Header().Set("Content-Type", "application/json")
			err := json.NewEncoder(w).Encode(b)

			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}
		case "xml":
			x, err := xml.MarshalIndent(b, "", "  ")
			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}

			w.Header().Set("Content-Type", "application/xml")
			w.Write(x)

		case "html":
			w.Header().Set("Content-Type", "text/html")
			io.WriteString(w, "
URL: "+b.URL+"
")
			io.WriteString(w, "
Delete Key: "+b.DELKEY+"
")

		case "redirect":
			http.Redirect(w, r, b.URL, 301)

		default:
			w.Header().Set("Content-Type", "plain/text")
			io.WriteString(w, b.URL+"\n")
			io.WriteString(w, "delete key: "+b.DELKEY+"\n")
		}
	}

}

func highlight(s string, lang string) (string, error) {

	highlight, err := pygments.Highlight(html.UnescapeString(s), html.EscapeString(lang), "html", "style=autumn,linenos=True, lineanchors=True,anchorlinenos=True,noclasses=True,", "utf-8")
	if err != nil {
		return "", err
	}
	return highlight, nil

}

func getPaste(paste string, lang string) (string, string) {
	param1 := html.EscapeString(paste)
	db, err := sql.Open("mysql", DATABASE)
	var title, s string
	var expiry string
	err = db.QueryRow("select title, data, expiry from pastebin where id=?", param1).Scan(&title, &s, &expiry)
	check(err)
	fmt.Println(expiry)
	fmt.Println(time.Now().Format(time.RFC3339))
	fmt.Println(expiry > time.Now().Format(time.RFC3339))
	if expiry > time.Now().Format(time.RFC3339) {
		stmt, err := db.Prepare("delete from pastebin where id=?")
		check(err)
		_, err = stmt.Exec(param1)
		check(err)
		return "Error invalid paste", ""
	}
	db.Close()

	if err == sql.ErrNoRows {
		return "Error invalid paste", ""
	} else {
		if lang == "" {
			return html.UnescapeString(s), html.UnescapeString(title)
		} else {
			high, err := highlight(s, lang)
			check(err)
			return high, html.UnescapeString(title)

		}
	}

}

var templates = template.Must(template.ParseFiles("assets/paste.html", "assets/index.html", "assets/clone.html"))
var syntax, _ = ioutil.ReadFile("assets/syntax.html")

func pasteHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	lang := vars["lang"]
	s, title := getPaste(paste, lang)
	link := ADDRESS + "/raw/" + paste
	download := ADDRESS + "/download/" + paste
	clone := ADDRESS + "/clone/" + paste
	if lang == "" {
		p := &Page{
			Title:    title,
			Body:     []byte(s),
			Raw:      link,
			Home:     ADDRESS,
			Download: download,
			Clone:    clone,
		}
		err := templates.ExecuteTemplate(w, "paste.html", p)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
		}

	} else {
		fmt.Fprintf(w, string(syntax), paste, paste, s, ADDRESS, download, link, clone)

	}
}

func cloneHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	s, title := getPaste(paste, "")
	link := ADDRESS + "/raw/" + paste
	download := ADDRESS + "/download/" + paste
	clone := ADDRESS + "/clone/" + paste
	p := &Page{
		Title:    title,
		Body:     []byte(s),
		Raw:      link,
		Home:     ADDRESS,
		Download: download,
		Clone:    clone,
	}
	err := templates.ExecuteTemplate(w, "clone.html", p)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

}
func downloadHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	s, _ := getPaste(paste, "")
	w.Header().Set("Content-Disposition", "attachment; filename="+paste)
	w.Header().Set("Content-Type", r.Header.Get("Content-Type"))
	io.WriteString(w, s)

}
func rawHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	s, _ := getPaste(paste, "")
	io.WriteString(w, s)

}

func main() {
	router := mux.NewRouter()
	router.HandleFunc("/p/{pasteId}", pasteHandler)
	router.HandleFunc("/raw/{pasteId}", rawHandler)
	router.HandleFunc("/p/{pasteId}/{lang}", pasteHandler)
	router.HandleFunc("/clone/{pasteId}", cloneHandler)
	router.HandleFunc("/download/{pasteId}", downloadHandler)
	router.HandleFunc("/save", saveHandler)
	router.HandleFunc("/save/{output}", saveHandler)
	router.HandleFunc("/del/{pasteId}/{delKey}", delHandler)
	router.PathPrefix("/").Handler(http.StripPrefix("/", http.FileServer(http.Dir("assets/"))))
	err := http.ListenAndServe(PORT, router)
	if err != nil {
		log.Fatal(err)
	}

}
<commit_msg>Fix up expiry<commit_after>package main

import (
	"crypto/sha1"
	"database/sql"
	"encoding/base64"
	"encoding/json"
	"encoding/xml"
	"fmt"
	"html"
	"html/template"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"time"

	"github.com/dchest/uniuri"
	"github.com/ewhal/pygments"
	_ "github.com/go-sql-driver/mysql"
	"github.com/gorilla/mux"
)

const (
	ADDRESS  = "http://localhost:9900"
	LENGTH   = 6
	PORT     = ":9900"
	USERNAME = ""
	PASS     = ""
	NAME     = ""
	DATABASE = USERNAME + ":" + PASS + "@/" + NAME + "?charset=utf8"
)

type Response struct {
	ID     string `json:"id"`
	TITLE  string `json:"title"`
	HASH   string `json:"hash"`
	URL    string `json:"url"`
	SIZE   int    `json:"size"`
	DELKEY string `json:"delkey"`
}

type Page struct {
	Title    string
	Body     []byte
	Raw      string
	Home     string
	Download string
	Clone    string
}

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

func generateName() string {
	s := uniuri.NewLen(LENGTH)
	db, err := sql.Open("mysql", DATABASE)
	check(err)

	query, err := db.Query("select id from pastebin")
	for query.Next() {
		var id string
		err := query.Scan(&id)
		if err != nil {

		}
		if id == s {
			generateName()
		}
	}
	db.Close()

	return s

}
func hash(paste string) string {
	hasher := sha1.New()

	hasher.Write([]byte(paste))
	sha := base64.URLEncoding.EncodeToString(hasher.Sum(nil))
	return sha
}

func save(raw string, lang string, title string, expiry string) []string {
	db, err := sql.Open("mysql", DATABASE)
	check(err)

	sha := hash(raw)
	query, err := db.Query("select id, title, hash, data, delkey from pastebin")
	for query.Next() {
		var id, title, hash, paste, delkey string
		err := query.Scan(&id, &title, &hash, &paste, &delkey)
		check(err)
		if hash == sha {
			url := ADDRESS + "/p/" + id
			return []string{id, title, hash, url, paste, delkey}
		}
	}
	id := generateName()
	var url string
	if lang == "" {
		url = ADDRESS + "/p/" + id
	} else {
		url = ADDRESS + "/p/" + id + "/" + lang
	}
	now := time.Now()
	var expiryTime string

	switch expiry {
	case "5 minutes":
		expiryTime = now.Add(time.Minute * 5).Format("2006-01-02 15:04:05")
		break

	case "1 hour":
		expiryTime = now.Add(time.Hour + 1).Format("2006-01-02 15:04:05")
		break

	case "1 day":
		expiryTime = now.Add(time.Hour * 24 * 1).Format("2006-01-02 15:04:05")
		break

	case "1 week":
		expiryTime = now.Add(time.Hour * 24 * 7).Format("2006-01-02 15:04:05")
		break

	case "1 month":
		expiryTime = now.Add(time.Hour * 24 * 30).Format("2006-01-02 15:04:05")
		break

	case "1 year":
		expiryTime = now.Add(time.Hour * 24 * 365).Format("2006-01-02 15:04:05")
		break

	default:
		expiryTime = now.Format("2006-01-02 15:04:05")
		break

	}
	delKey := uniuri.NewLen(40)
	paste := html.EscapeString(raw)

	stmt, err := db.Prepare("INSERT INTO pastebin(id, title, hash, data, delkey, expiry) values(?,?,?,?,?,?)")
	check(err)
	if title == "" {
		_, err = stmt.Exec(id, id, sha, paste, delKey, expiryTime)
		check(err)
	} else {
		_, err = stmt.Exec(id, html.EscapeString(title), sha, paste, delKey, expiryTime)
		check(err)
	}
	db.Close()
	return []string{id, title, sha, url, paste, delKey}
}

func delHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	delkey := vars["delKey"]

	db, err := sql.Open("mysql", DATABASE)
	check(err)

	stmt, err := db.Prepare("delete from pastebin where delkey=?")
	check(err)

	res, err := stmt.Exec(html.EscapeString(delkey))
	check(err)

	_, err = res.RowsAffected()
	if err == sql.ErrNoRows {
		io.WriteString(w, "Error invalid paste")
	} else {
		io.WriteString(w, paste+" deleted")
	}
	db.Close()

}
func saveHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	output := vars["output"]
	switch r.Method {
	case "POST":
		paste := r.FormValue("p")
		lang := r.FormValue("lang")
		title := r.FormValue("title")
		expiry := r.FormValue("expiry")
		if paste == "" {
			http.Error(w, "Empty paste", 500)
			return
		}
		values := save(paste, lang, title, expiry)
		b := &Response{
			ID:     values[0],
			TITLE:  values[1],
			HASH:   values[2],
			URL:    values[3],
			SIZE:   len(values[4]),
			DELKEY: values[5],
		}

		switch output {
		case "json":

			w.Header().Set("Content-Type", "application/json")
			err := json.NewEncoder(w).Encode(b)

			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}
		case "xml":
			x, err := xml.MarshalIndent(b, "", "  ")
			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}

			w.Header().Set("Content-Type", "application/xml")
			w.Write(x)

		case "html":
			w.Header().Set("Content-Type", "text/html")
			io.WriteString(w, "
URL: "+b.URL+"
")
			io.WriteString(w, "
Delete Key: "+b.DELKEY+"
")

		case "redirect":
			http.Redirect(w, r, b.URL, 301)

		default:
			w.Header().Set("Content-Type", "plain/text")
			io.WriteString(w, b.URL+"\n")
			io.WriteString(w, "delete key: "+b.DELKEY+"\n")
		}
	}

}

func highlight(s string, lang string) (string, error) {

	highlight, err := pygments.Highlight(html.UnescapeString(s), html.EscapeString(lang), "html", "style=autumn,linenos=True, lineanchors=True,anchorlinenos=True,noclasses=True,", "utf-8")
	if err != nil {
		return "", err
	}
	return highlight, nil

}

func getPaste(paste string, lang string) (string, string) {
	param1 := html.EscapeString(paste)
	db, err := sql.Open("mysql", DATABASE)
	var title, s string
	var expiry string
	err = db.QueryRow("select title, data, expiry from pastebin where id=?", param1).Scan(&title, &s, &expiry)
	check(err)
	if time.Now().Format("2006-01-02 15:04:05") > expiry {
		stmt, err := db.Prepare("delete from pastebin where id=?")
		check(err)
		_, err = stmt.Exec(param1)
		check(err)
		return "Error invalid paste", ""
	}
	db.Close()

	if err == sql.ErrNoRows {
		return "Error invalid paste", ""
	} else {
		if lang == "" {
			return html.UnescapeString(s), html.UnescapeString(title)
		} else {
			high, err := highlight(s, lang)
			check(err)
			return high, html.UnescapeString(title)

		}
	}

}

var templates = template.Must(template.ParseFiles("assets/paste.html", "assets/index.html", "assets/clone.html"))
var syntax, _ = ioutil.ReadFile("assets/syntax.html")

func pasteHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	lang := vars["lang"]
	s, title := getPaste(paste, lang)
	link := ADDRESS + "/raw/" + paste
	download := ADDRESS + "/download/" + paste
	clone := ADDRESS + "/clone/" + paste
	if lang == "" {
		p := &Page{
			Title:    title,
			Body:     []byte(s),
			Raw:      link,
			Home:     ADDRESS,
			Download: download,
			Clone:    clone,
		}
		err := templates.ExecuteTemplate(w, "paste.html", p)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
		}

	} else {
		fmt.Fprintf(w, string(syntax), paste, paste, s, ADDRESS, download, link, clone)

	}
}

func cloneHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	s, title := getPaste(paste, "")
	link := ADDRESS + "/raw/" + paste
	download := ADDRESS + "/download/" + paste
	clone := ADDRESS + "/clone/" + paste
	p := &Page{
		Title:    title,
		Body:     []byte(s),
		Raw:      link,
		Home:     ADDRESS,
		Download: download,
		Clone:    clone,
	}
	err := templates.ExecuteTemplate(w, "clone.html", p)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

}
func downloadHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	s, _ := getPaste(paste, "")
	w.Header().Set("Content-Disposition", "attachment; filename="+paste)
	w.Header().Set("Content-Type", r.Header.Get("Content-Type"))
	io.WriteString(w, s)

}
func rawHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	s, _ := getPaste(paste, "")
	io.WriteString(w, s)

}

func main() {
	router := mux.NewRouter()
	router.HandleFunc("/p/{pasteId}", pasteHandler)
	router.HandleFunc("/raw/{pasteId}", rawHandler)
	router.HandleFunc("/p/{pasteId}/{lang}", pasteHandler)
	router.HandleFunc("/clone/{pasteId}", cloneHandler)
	router.HandleFunc("/download/{pasteId}", downloadHandler)
	router.HandleFunc("/save", saveHandler)
	router.HandleFunc("/save/{output}", saveHandler)
	router.HandleFunc("/del/{pasteId}/{delKey}", delHandler)
	router.PathPrefix("/").Handler(http.StripPrefix("/", http.FileServer(http.Dir("assets/"))))
	err := http.ListenAndServe(PORT, router)
	if err != nil {
		log.Fatal(err)
	}

}
<|endoftext|>


<commit_before>/*
Gapstone is a Go binding for the Capstone disassembly library. For examples,
try reading the *_test.go files.

	Library Author: Nguyen Anh Quynh
	Binding Author: Ben Nagy
	License: BSD style - see LICENSE file for details
    (c) 2013 COSEINC. All Rights Reserved.
*/
package gapstone

// #cgo pkg-config: capstone
// #include <stdlib.h>
// #include <capstone.h>
import "C"
import "unsafe"
import "reflect"
import "fmt"

type Errno int

func (e Errno) Error() string {
	s := C.GoString(C.cs_strerror(C.cs_err(e)))
	if s == "" {
		return fmt.Sprintf("Internal Error: No Error string for Errno %v", e)
	}
	return s
}

var (
	ErrOK       error = Errno(0)
	ErrOOM      error = Errno(1)
	ErrArch     error = Errno(2)
	ErrHandle   error = Errno(3)
	ErrArg      error = Errno(4)
	ErrMode     error = Errno(5)
	ErrOption   error = Errno(6)
	ErrDetail   error = Errno(7)
	ErrMemSetup error = Errno(8)
	ErrVersion  error = Errno(9)
	ErrDiet     error = Errno(10)
)

// The arch and mode given at create time will determine how code is
// disassembled. After use you must close an Engine with engine.Close() to allow
// the C lib to free resources.
type Engine struct {
	handle C.csh
	arch   int
	mode   uint
}

// Information that exists for every Instruction, regardless of arch.
// Structure members here will be promoted, so every Instruction will have
// them available. Check the constants for each architecture for available
// Instruction groups etc.
type InstructionHeader struct {
	Id       uint   // Internal id for this instruction. Subject to change.
	Address  uint   // Nominal address ($ip) of this instruction
	Size     uint   // Size of the instruction, in bytes
	Bytes    []byte // Raw Instruction bytes
	Mnemonic string // Ascii text of instruction mnemonic
	OpStr    string // Ascii text of instruction operands - Syntax depends on CS_OPT_SYNTAC
	// Nothing below is available without the decomposer. BE CAREFUL! By
	// default, CS_OPT_DETAIL is set to CS_OPT_OFF so the result of accessing
	// these members is undefined.
	RegistersRead    []uint // List of implicit registers read by this instruction
	RegistersWritten []uint // List of implicit registers written by this instruction
	Groups           []uint // List of *_GRP_* groups this instruction belongs to.
}

// arch specific information will be filled in for exactly one of the
// substructures. Eg, an Engine created with New(CS_ARCH_ARM, CS_MODE_ARM) will
// fill in only the Arm structure member.
type Instruction struct {
	InstructionHeader
	Arm   ArmInstruction
	Arm64 Arm64Instruction
	Mips  MipsInstruction
	X86   X86Instruction
	PPC   PPCInstruction
}

// Called by the arch specific decomposers
func fillGenericHeader(raw C.cs_insn, insn *Instruction) {

	insn.Id = uint(raw.id)
	insn.Address = uint(raw.address)
	insn.Size = uint(raw.size)
	insn.Mnemonic = C.GoString(&raw.mnemonic[0])
	insn.OpStr = C.GoString(&raw.op_str[0])

	var bslice []byte
	h := (*reflect.SliceHeader)(unsafe.Pointer(&bslice))
	h.Data = uintptr(unsafe.Pointer(&raw.bytes[0]))
	h.Len = int(raw.size)
	h.Cap = int(raw.size)
	insn.Bytes = bslice

	if raw.detail != nil {
		for i := 0; i < int(raw.detail.regs_read_count); i++ {
			insn.RegistersRead = append(insn.RegistersRead, uint(raw.detail.regs_read[i]))
		}

		for i := 0; i < int(raw.detail.regs_write_count); i++ {
			insn.RegistersWritten = append(insn.RegistersWritten, uint(raw.detail.regs_write[i]))
		}

		for i := 0; i < int(raw.detail.groups_count); i++ {
			insn.Groups = append(insn.Groups, uint(raw.detail.groups[i]))
		}
	}

}

// Close the underlying C handle and resources used by this Engine
func (e Engine) Close() error {
	res := C.cs_close(&e.handle)
	return Errno(res)
}

// Accessor for the Engine architecture CS_ARCH_*
func (e Engine) Arch() int { return e.arch }

// Accessor for the Engine mode CS_MODE_*
func (e Engine) Mode() uint { return e.mode }

// Check if a particular arch is supported by this engine.
// To verify if this engine supports everything, use CS_ARCH_ALL
func (e Engine) Support(arch int) bool { return bool(C.cs_support(C.int(arch))) }

// Version information.
func (e Engine) Version() (maj, min int) {
	C.cs_version((*C.int)(unsafe.Pointer(&maj)), (*C.int)(unsafe.Pointer(&min)))
	return
}

// Getter for the last Errno from the engine. Normal code shouldn't need to
// access this directly, but it's exported just in case.
func (e Engine) Errno() error { return Errno(C.cs_errno(e.handle)) }

// The arch is implicit in the Engine. Accepts either a constant like ARM_REG_R0
// or insn.Arm.Operands[0].Reg, or anything that refers to a Register like
// insn.X86.SibBase etc
func (e Engine) RegName(reg uint) string {
	return C.GoString(C.cs_reg_name(e.handle, C.uint(reg)))
}

// The arch is implicit in the Engine. Accepts a constant like
// ARM_INSN_ADD, or insn.Id
func (e Engine) InsnName(insn uint) string {
	return C.GoString(C.cs_insn_name(e.handle, C.uint(insn)))
}

// Setter for Engine options CS_OPT_*
func (e Engine) SetOption(ty, value uint) error {
	res := C.cs_option(
		e.handle,
		C.cs_opt_type(ty),
		C.size_t(value),
	)

	if Errno(res) == ErrOK {
		return nil
	}
	return Errno(res)
}

// Disassemble a []byte full of opcodes.
//   * address - Address of the first instruction in the given code buffer.
//   * count - Number of instructions to disassemble, 0 to disassemble the whole []byte
//
// Underlying C resources are automatically free'd by this function.
func (e Engine) Disasm(input []byte, address, count uint64) ([]Instruction, error) {

	var insn *C.cs_insn
	bptr := (*C.uint8_t)(unsafe.Pointer(&input[0]))
	disassembled := C.cs_disasm_ex(
		e.handle,
		bptr,
		C.size_t(len(input)),
		C.uint64_t(address),
		C.size_t(count),
		&insn,
	)

	if disassembled > 0 {
		defer C.cs_free((*C.cs_insn)(unsafe.Pointer(insn)), C.size_t(disassembled))
		// Create a slice, and reflect its header
		var insns []C.cs_insn
		h := (*reflect.SliceHeader)(unsafe.Pointer(&insns))
		// Manually fill in the ptr, len and cap from the raw C data
		h.Data = uintptr(unsafe.Pointer(insn))
		h.Len = int(disassembled)
		h.Cap = int(disassembled)

		switch e.arch {
		case CS_ARCH_ARM:
			return decomposeArm(insns), nil
		case CS_ARCH_ARM64:
			return decomposeArm64(insns), nil
		case CS_ARCH_MIPS:
			return decomposeMips(insns), nil
		case CS_ARCH_X86:
			return decomposeX86(insns), nil
		case CS_ARCH_PPC:
			return decomposePPC(insns), nil
		default:
			return []Instruction{}, ErrArch
		}
	}
	return []Instruction{}, e.Errno()
}

// Create a new Engine with the specified arch and mode
func New(arch int, mode uint) (Engine, error) {
	var handle C.csh
	res := C.cs_open(C.cs_arch(arch), C.cs_mode(mode), &handle)
	if Errno(res) == ErrOK {
		return Engine{handle, arch, mode}, nil
	}
	return Engine{0, CS_ARCH_MAX, 0}, Errno(res)
}
<commit_msg>more fully support diet mode<commit_after>/*
Gapstone is a Go binding for the Capstone disassembly library. For examples,
try reading the *_test.go files.

	Library Author: Nguyen Anh Quynh
	Binding Author: Ben Nagy
	License: BSD style - see LICENSE file for details
    (c) 2013 COSEINC. All Rights Reserved.
*/
package gapstone

// #cgo pkg-config: capstone
// #include <stdlib.h>
// #include <capstone.h>
import "C"
import "unsafe"
import "reflect"
import "fmt"

type Errno int

func (e Errno) Error() string {
	s := C.GoString(C.cs_strerror(C.cs_err(e)))
	if s == "" {
		return fmt.Sprintf("Internal Error: No Error string for Errno %v", e)
	}
	return s
}

var (
	ErrOK       error = Errno(0)
	ErrOOM      error = Errno(1)
	ErrArch     error = Errno(2)
	ErrHandle   error = Errno(3)
	ErrArg      error = Errno(4)
	ErrMode     error = Errno(5)
	ErrOption   error = Errno(6)
	ErrDetail   error = Errno(7)
	ErrMemSetup error = Errno(8)
	ErrVersion  error = Errno(9)
	ErrDiet     error = Errno(10)
)

// Since this is a build-time option for the C lib, it seems logical to have
// this as a static flag.
// Diet Mode Changes:
// - No regs_read, regs_written or groups
// - No response to reg_name or insn_name
// - No mnemonic or op_str
// If you want to see any operands in diet mode, then you need CS_DETAIL.
var dietMode = bool(C.cs_support(CS_SUPPORT_DIET))

// The arch and mode given at create time will determine how code is
// disassembled. After use you must close an Engine with engine.Close() to allow
// the C lib to free resources.
type Engine struct {
	handle C.csh
	arch   int
	mode   uint
}

// Information that exists for every Instruction, regardless of arch.
// Structure members here will be promoted, so every Instruction will have
// them available. Check the constants for each architecture for available
// Instruction groups etc.
type InstructionHeader struct {
	Id      uint   // Internal id for this instruction. Subject to change.
	Address uint   // Nominal address ($ip) of this instruction
	Size    uint   // Size of the instruction, in bytes
	Bytes   []byte // Raw Instruction bytes
	// Not available in diet mode ( capstone built with CAPSTONE_DIET=yes )
	Mnemonic string // Ascii text of instruction mnemonic
	OpStr    string // Ascii text of instruction operands - Syntax depends on CS_OPT_SYNTAC
	// Not available without the decomposer. BE CAREFUL! By default,
	// CS_OPT_DETAIL is set to CS_OPT_OFF so the result of accessing these
	// members is undefined.
	RegistersRead    []uint // List of implicit registers read by this instruction
	RegistersWritten []uint // List of implicit registers written by this instruction
	Groups           []uint // List of *_GRP_* groups this instruction belongs to.
}

// arch specific information will be filled in for exactly one of the
// substructures. Eg, an Engine created with New(CS_ARCH_ARM, CS_MODE_ARM) will
// fill in only the Arm structure member.
type Instruction struct {
	InstructionHeader
	Arm   ArmInstruction
	Arm64 Arm64Instruction
	Mips  MipsInstruction
	X86   X86Instruction
	PPC   PPCInstruction
}

// Called by the arch specific decomposers
func fillGenericHeader(raw C.cs_insn, insn *Instruction) {

	insn.Id = uint(raw.id)
	insn.Address = uint(raw.address)
	insn.Size = uint(raw.size)

	if !dietMode {
		insn.Mnemonic = C.GoString(&raw.mnemonic[0])
		insn.OpStr = C.GoString(&raw.op_str[0])
	}

	var bslice []byte
	h := (*reflect.SliceHeader)(unsafe.Pointer(&bslice))
	h.Data = uintptr(unsafe.Pointer(&raw.bytes[0]))
	h.Len = int(raw.size)
	h.Cap = int(raw.size)
	insn.Bytes = bslice

	if raw.detail != nil && !dietMode {
		for i := 0; i < int(raw.detail.regs_read_count); i++ {
			insn.RegistersRead = append(insn.RegistersRead, uint(raw.detail.regs_read[i]))
		}

		for i := 0; i < int(raw.detail.regs_write_count); i++ {
			insn.RegistersWritten = append(insn.RegistersWritten, uint(raw.detail.regs_write[i]))
		}

		for i := 0; i < int(raw.detail.groups_count); i++ {
			insn.Groups = append(insn.Groups, uint(raw.detail.groups[i]))
		}
	}

}

// Close the underlying C handle and resources used by this Engine
func (e Engine) Close() error {
	res := C.cs_close(&e.handle)
	return Errno(res)
}

// Accessor for the Engine architecture CS_ARCH_*
func (e Engine) Arch() int { return e.arch }

// Accessor for the Engine mode CS_MODE_*
func (e Engine) Mode() uint { return e.mode }

// Check if a particular arch is supported by this engine.
// To verify if this engine supports everything, use CS_ARCH_ALL
func (e Engine) Support(arch int) bool { return bool(C.cs_support(C.int(arch))) }

// Version information.
func (e Engine) Version() (maj, min int) {
	C.cs_version((*C.int)(unsafe.Pointer(&maj)), (*C.int)(unsafe.Pointer(&min)))
	return
}

// Getter for the last Errno from the engine. Normal code shouldn't need to
// access this directly, but it's exported just in case.
func (e Engine) Errno() error { return Errno(C.cs_errno(e.handle)) }

// The arch is implicit in the Engine. Accepts either a constant like ARM_REG_R0
// or insn.Arm.Operands[0].Reg, or anything that refers to a Register like
// insn.X86.SibBase etc
//
// WARNING: Always returns "" if capstone built with CAPSTONE_DIET
func (e Engine) RegName(reg uint) string {
	if dietMode {
		return ""
	}
	return C.GoString(C.cs_reg_name(e.handle, C.uint(reg)))
}

// The arch is implicit in the Engine. Accepts a constant like
// ARM_INSN_ADD, or insn.Id
//
// WARNING: Always returns "" if capstone built with CAPSTONE_DIET
func (e Engine) InsnName(insn uint) string {
	if dietMode {
		return ""
	}
	return C.GoString(C.cs_insn_name(e.handle, C.uint(insn)))
}

// Setter for Engine options CS_OPT_*
func (e Engine) SetOption(ty, value uint) error {
	res := C.cs_option(
		e.handle,
		C.cs_opt_type(ty),
		C.size_t(value),
	)

	if Errno(res) == ErrOK {
		return nil
	}
	return Errno(res)
}

// Disassemble a []byte full of opcodes.
//   * address - Address of the first instruction in the given code buffer.
//   * count - Number of instructions to disassemble, 0 to disassemble the whole []byte
//
// Underlying C resources are automatically free'd by this function.
func (e Engine) Disasm(input []byte, address, count uint64) ([]Instruction, error) {

	var insn *C.cs_insn
	bptr := (*C.uint8_t)(unsafe.Pointer(&input[0]))
	disassembled := C.cs_disasm_ex(
		e.handle,
		bptr,
		C.size_t(len(input)),
		C.uint64_t(address),
		C.size_t(count),
		&insn,
	)

	if disassembled > 0 {
		defer C.cs_free((*C.cs_insn)(unsafe.Pointer(insn)), C.size_t(disassembled))
		// Create a slice, and reflect its header
		var insns []C.cs_insn
		h := (*reflect.SliceHeader)(unsafe.Pointer(&insns))
		// Manually fill in the ptr, len and cap from the raw C data
		h.Data = uintptr(unsafe.Pointer(insn))
		h.Len = int(disassembled)
		h.Cap = int(disassembled)

		switch e.arch {
		case CS_ARCH_ARM:
			return decomposeArm(insns), nil
		case CS_ARCH_ARM64:
			return decomposeArm64(insns), nil
		case CS_ARCH_MIPS:
			return decomposeMips(insns), nil
		case CS_ARCH_X86:
			return decomposeX86(insns), nil
		case CS_ARCH_PPC:
			return decomposePPC(insns), nil
		default:
			return []Instruction{}, ErrArch
		}
	}
	return []Instruction{}, e.Errno()
}

// Create a new Engine with the specified arch and mode
func New(arch int, mode uint) (Engine, error) {
	var handle C.csh
	res := C.cs_open(C.cs_arch(arch), C.cs_mode(mode), &handle)
	if Errno(res) == ErrOK {
		return Engine{handle, arch, mode}, nil
	}
	return Engine{0, CS_ARCH_MAX, 0}, Errno(res)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"github.com/gokyle/goconfig"
	"io/ioutil"
	"log"
	"net/http"
	"os"
)

func get(src string) ([]byte, error) {
	resp, err := http.Get(src)
	errr(err, "Can't make http request")

	defer resp.Body.Close()

	return ioutil.ReadAll(resp.Body)
}

func write(data []byte, path string) error {
	file, err := os.Create(path)
	if err != nil {
		return err
	}

	defer file.Close()

	w := bufio.NewWriter(file)
	file.Write(data)

	return w.Flush()
}

func errr(e error, msg string) {
	if e != nil {
		log.Printf("[!]: %s - %s", msg, e)
	}
}

func main() {
	var conf, err = goconfig.ParseFile("config.ini")
	var url = conf["global"]["url"]
	var params string = "?"

	for key, val := range conf["params"] {
		params = params + key + "=" + val + "&"
	}

	errr(err, "Can't parse config file!")
	log.Printf("Getting lists from: %s", url)

	for key, val := range conf["list"] {
		var full_url = url + params + "list=" + val
		log.Printf("downloading %s", key)
		data, err := get(full_url)
		write(data, "/tmp/"+key+".gz")
		errr(err, "Error getting "+full_url)
	}
}
<commit_msg>file name<commit_after>package main

import (
	"bufio"
	"github.com/gokyle/goconfig"
	"io/ioutil"
	"log"
	"net/http"
	"os"
)

func get(src string) ([]byte, error) {
	resp, err := http.Get(src)
	errr(err, "Can't make http request")

	defer resp.Body.Close()

	return ioutil.ReadAll(resp.Body)
}

func write(data []byte, path string) error {
	file, err := os.Create(path)
	if err != nil {
		return err
	}

	defer file.Close()

	w := bufio.NewWriter(file)
	file.Write(data)

	return w.Flush()
}

func errr(e error, msg string) {
	if e != nil {
		log.Printf("[!]: %s - %s", msg, e)
	}
}

func main() {
	var conf, err = goconfig.ParseFile("config.ini")
	var url = conf["global"]["url"]
	var params string = "?"

	for key, val := range conf["params"] {
		params = params + key + "=" + val + "&"
	}

	errr(err, "Can't parse config file!")
	log.Printf("Getting lists from: %s", url)

	for key, val := range conf["list"] {
		var full_url = url + params + "list=" + val
		var file_name = "/tmp" + key + ".gz"

		log.Printf("downloading %s", key)
		data, err := get(full_url)

		write(data, file_name)
		errr(err, "Error getting "+full_url)
	}
}
<|endoftext|>