<commit_before>package commenttags

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

type DirectoryData struct {
	Dirname string
	Files   []FileData
}

func ProcessDirectory(name string, maxSize int64) (*DirectoryData, error) {
	fmt.Println("ProcessDirectory", name)

	data := DirectoryData{}
	data.Dirname = name

	dir, err := ioutil.ReadDir(name)
	if err != nil {
		return &data, err
	}
	if len(dir) != 0 {
		for _, v := range dir {
			// fmt.Printf("Check %s %d %# v\n", name, k, v.Name())
			// check file or folder
			if v.IsDir() {
				// ignore som filders like .git
				if v.Name() != ".git" {
					tmp, _ := ProcessDirectory(name+"/"+v.Name(), maxSize)
					// HACK: exception handler...
					for _, v := range tmp.Files {
						data.Files = append(data.Files, v)
					}
				}
			} else {
				// fmt.Println("Is File...")
				// TODO: check filesize  v.Size() < maxSize
				tmpFiles, errFiles := ProcessFile(name + "/" + v.Name())
				if errFiles != nil {
					return &DirectoryData{}, errFiles
				}
				// if tags exist, add to the files array
				if len(tmpFiles.Tags) > 0 {
					data.Files = append(data.Files, *tmpFiles)
				}
			}
		}
	}
	return &data, nil
}

func (d *DirectoryData) PrettyPrint() {
	for _, v := range d.Files {
		v.PrettyPrint()
	}
}

func (d *DirectoryData) SaveJSON(filename string, perm os.FileMode) error {
	data, err := json.Marshal(d)
	if err != nil {
		return err
	}
	err = ioutil.WriteFile(filename, data, perm)
	return err
}

func ParseJSON(data []byte) (DirectoryData, error) {
	v := DirectoryData{}
	err := json.Unmarshal(data, &v)
	return v, err
}

func ReadJSON(filename string) (*DirectoryData, error) {
	data, err := ioutil.ReadFile(filename)
	if err != nil {
		return &DirectoryData{}, err
	}
	v, errParse := ParseJSON(data)
	return &v, errParse
}
<commit_msg>ProcessDirectory return nil if read dir failed, small pointer changes (more common)<commit_after>package commenttags

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

type DirectoryData struct {
	Dirname string
	Files   []FileData
}

func ProcessDirectory(name string, maxSize int64) (*DirectoryData, error) {
	fmt.Println("ProcessDirectory", name)
	data := &DirectoryData{}
	data.Dirname = name

	dir, err := ioutil.ReadDir(name)
	if err != nil {
		return nil, err
	}
	if len(dir) != 0 {
		for _, v := range dir {
			// fmt.Printf("Check %s %d %# v\n", name, k, v.Name())
			// check file or folder
			if v.IsDir() {
				// ignore som filders like .git
				if v.Name() != ".git" {
					tmp, _ := ProcessDirectory(name+"/"+v.Name(), maxSize)
					// HACK: exception handler...
					for _, v := range tmp.Files {
						data.Files = append(data.Files, v)
					}
				}
			} else {
				// fmt.Println("Is File...")
				// TODO: check filesize  v.Size() < maxSize
				tmpFiles, errFiles := ProcessFile(name + "/" + v.Name())
				if errFiles != nil {
					return nil, errFiles
				}
				// if tags exist, add to the files array
				if len(tmpFiles.Tags) > 0 {
					data.Files = append(data.Files, *tmpFiles)
				}
			}
		}
	}
	return data, nil
}

func (d *DirectoryData) PrettyPrint() {
	for _, v := range d.Files {
		v.PrettyPrint()
	}
}

func (d *DirectoryData) SaveJSON(filename string, perm os.FileMode) error {
	data, err := json.Marshal(d)
	if err != nil {
		return err
	}
	err = ioutil.WriteFile(filename, data, perm)
	return err
}

func ParseJSON(data []byte) (DirectoryData, error) {
	v := DirectoryData{}
	err := json.Unmarshal(data, &v)
	return v, err
}

func ReadJSON(filename string) (*DirectoryData, error) {
	data, err := ioutil.ReadFile(filename)
	if err != nil {
		return &DirectoryData{}, err
	}
	v, errParse := ParseJSON(data)
	return &v, errParse
}
<|endoftext|>


<commit_before>package yum

import (
	"testing"

	"github.com/hnakamur/commango/jsonutil"
)

func TestInstalled(t *testing.T) {
	result, err := Installed("kernel")
	if err != nil {
		t.Fatal(err)
	}

    _, err = jsonutil.Encode(result)
	if err != nil {
		t.Fatal(err)
	}
}

func TestNotInstalled(t *testing.T) {
	result, err := Installed("no_such_package")
	if err != nil {
		t.Fatal(err)
	}

    _, err = jsonutil.Encode(result)
	if err != nil {
		t.Fatal(err)
	}
}

func TestInstallGroup(t *testing.T) {
	result, err := Install(`@'Development tools'`)
	if err != nil {
		t.Fatal(err)
	}

    json, err := jsonutil.Encode(result)
	if err != nil {
		t.Fatal(err)
	}
    t.Error(json)
}

func TestInstall(t *testing.T) {
	result, err := Install("make")
	if err != nil {
		t.Fatal(err)
	}

    json, err := jsonutil.Encode(result)
	if err != nil {
		t.Fatal(err)
	}
    t.Error(json)
}
<commit_msg>Remove debug prints in test.<commit_after>package yum

import (
	"testing"

	"github.com/hnakamur/commango/jsonutil"
)

func TestInstalled(t *testing.T) {
	result, err := Installed("kernel")
	if err != nil {
		t.Fatal(err)
	}

    _, err = jsonutil.Encode(result)
	if err != nil {
		t.Fatal(err)
	}
}

func TestNotInstalled(t *testing.T) {
	result, err := Installed("no_such_package")
	if err != nil {
		t.Fatal(err)
	}

    _, err = jsonutil.Encode(result)
	if err != nil {
		t.Fatal(err)
	}
}

func TestInstallGroup(t *testing.T) {
	result, err := Install("@'Development tools'")
	if err != nil {
		t.Fatal(err)
	}

    _, err = jsonutil.Encode(result)
	if err != nil {
		t.Fatal(err)
	}
}

func TestInstall(t *testing.T) {
	result, err := Install("make")
	if err != nil {
		t.Fatal(err)
	}

    _, err = jsonutil.Encode(result)
	if err != nil {
		t.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package main

import (
    //"fmt"
    "image"
    "image/color"
    //"image/gif"
    "os"
    //"bufio"
    "io"
    "compress/lzw"
    "bytes"
    "math"
)

func Encode(w io.Writer, m image.Image) error {
    b := m.Bounds()

    header := make([]byte, 0x320)

    header[0] = 'G'
    header[1] = 'I'
    header[2] = 'F'
    header[3] = '8'
    header[4] = '9'
    header[5] = 'a'

    header[7] = byte(b.Max.X / 255)
    header[6] = byte(b.Max.X % 255)
    header[9] = byte(b.Max.Y / 255)
    header[8] = byte(b.Max.Y % 255)

    header[0x0B] = byte(0x00) // Background color.
    header[0x0C] = byte(0x00) // Default pixel aspect ratio.

    // Grayscale color table.
    for i := byte(0); i < 255; i++ {
        header[0x0F + i] = i
        header[0x0E + i] = i
        header[0x0D + i] = i
    }

    header[0x30D] = byte(0x21) // GCE data header.
    header[0x30E] = byte(0xF9) // GCE data header (cont).
    header[0x30F] = byte(0x04) // Next 4 bytes are GCE data.
    header[0x310] = byte(0x01) // There is a transparent pixel.
    header[0x311] = byte(0x00) // Animation delay, LSB.
    header[0x312] = byte(0x00) // Animation delay, MSB.
    header[0x313] = byte(0x10) // And it is color #16 (0x10).
    header[0x314] = byte(0x00) // End of GCE data.

    header[0x315] = byte(0x2C) // Start of Image Descriptor.

    header[0x316] = byte(b.Min.X / 255)
    header[0x315] = byte(b.Min.X % 255)
    header[0x318] = byte(b.Min.Y / 255)
    header[0x317] = byte(b.Min.Y % 255)

    header[0x31B] = byte(b.Max.X / 255)
    header[0x31A] = byte(b.Max.X % 255)
    header[0x31D] = byte(b.Max.Y / 255)
    header[0x31C] = byte(b.Max.Y % 255)

    header[0x31E] = byte(0x00) // No local color table.

    header[0x31F] = byte(0x08) // Start of LZW with minimum code size 8.

    compressedImageBuffer := bytes.NewBuffer(make([]byte, 0, 255))
    lzww := lzw.NewWriter(compressedImageBuffer, lzw.LSB, int(8))

    for y := b.Min.Y; y < b.Max.Y; y++ {
        for x := b.Min.X; x < b.Max.X; x++ {
            c := color.GrayModel.Convert(m.At(x, y)).(color.Gray)
            lzww.Write([]byte{c.Y})
            //lzww.Write([]byte{byte(x ^ y)})
            //lzww.Write([]byte{byte(0x00)})
        }
    }
    lzww.Close()

    w.Write(header)

    const maxBlockSize = 255
    bytesSoFar := 0
    bytesRemaining := compressedImageBuffer.Len()
    for bytesRemaining > 0 {
        if bytesSoFar == 0 {
            blockSize := math.Min(maxBlockSize, float64(bytesRemaining))
            w.Write([]byte{byte(blockSize)})
        }

        b, _ :=  compressedImageBuffer.ReadByte()
        w.Write([]byte{b})

        bytesSoFar = (bytesSoFar + 1) % maxBlockSize
        bytesRemaining--
    }

    w.Write([]byte{0, ';'})

    return nil
}

func main() {
    m := image.NewRGBA(image.Rect(0, 0, 100, 100))
    m.Set(1, 1, color.RGBA{0x00, 0xFF, 0x00, 0xFF})
    file, _ := os.Create("new_image.gif")
    Encode(file, m)
}
<commit_msg>Move header writing to separate function<commit_after>package main

import (
    //"fmt"
    "image"
    "image/color"
    //"image/gif"
    "os"
    //"bufio"
    "io"
    "compress/lzw"
    "bytes"
    "math"
)

func writeHeader(w io.Writer, b image.Rectangle) {
    header := make([]byte, 0x320)

    header[0] = 'G'
    header[1] = 'I'
    header[2] = 'F'
    header[3] = '8'
    header[4] = '9'
    header[5] = 'a'

    header[7] = byte(b.Max.X / 255)
    header[6] = byte(b.Max.X % 255)
    header[9] = byte(b.Max.Y / 255)
    header[8] = byte(b.Max.Y % 255)

    header[0x0B] = byte(0x00) // Background color.
    header[0x0C] = byte(0x00) // Default pixel aspect ratio.

    // Grayscale color table.
    for i := byte(0); i < 255; i++ {
        header[0x0F + i] = i
        header[0x0E + i] = i
        header[0x0D + i] = i
    }

    header[0x30D] = byte(0x21) // GCE data header.
    header[0x30E] = byte(0xF9) // GCE data header (cont).
    header[0x30F] = byte(0x04) // Next 4 bytes are GCE data.
    header[0x310] = byte(0x01) // There is a transparent pixel.
    header[0x311] = byte(0x00) // Animation delay, LSB.
    header[0x312] = byte(0x00) // Animation delay, MSB.
    header[0x313] = byte(0x10) // And it is color #16 (0x10).
    header[0x314] = byte(0x00) // End of GCE data.

    header[0x315] = byte(0x2C) // Start of Image Descriptor.

    header[0x316] = byte(b.Min.X / 255)
    header[0x315] = byte(b.Min.X % 255)
    header[0x318] = byte(b.Min.Y / 255)
    header[0x317] = byte(b.Min.Y % 255)

    header[0x31B] = byte(b.Max.X / 255)
    header[0x31A] = byte(b.Max.X % 255)
    header[0x31D] = byte(b.Max.Y / 255)
    header[0x31C] = byte(b.Max.Y % 255)

    header[0x31E] = byte(0x00) // No local color table.

    header[0x31F] = byte(0x08) // Start of LZW with minimum code size 8.

    w.Write(header)
}

func Encode(w io.Writer, m image.Image) error {
    b := m.Bounds()
    writeHeader(w, b)

    compressedImageBuffer := bytes.NewBuffer(make([]byte, 0, 255))
    lzww := lzw.NewWriter(compressedImageBuffer, lzw.LSB, int(8))

    for y := b.Min.Y; y < b.Max.Y; y++ {
        for x := b.Min.X; x < b.Max.X; x++ {
            c := color.GrayModel.Convert(m.At(x, y)).(color.Gray)
            lzww.Write([]byte{c.Y})
            //lzww.Write([]byte{byte(x ^ y)})
            //lzww.Write([]byte{byte(0x00)})
        }
    }
    lzww.Close()

    const maxBlockSize = 255
    bytesSoFar := 0
    bytesRemaining := compressedImageBuffer.Len()
    for bytesRemaining > 0 {
        if bytesSoFar == 0 {
            blockSize := math.Min(maxBlockSize, float64(bytesRemaining))
            w.Write([]byte{byte(blockSize)})
        }

        b, _ :=  compressedImageBuffer.ReadByte()
        w.Write([]byte{b})

        bytesSoFar = (bytesSoFar + 1) % maxBlockSize
        bytesRemaining--
    }

    w.Write([]byte{0, ';'})

    return nil
}

func main() {
    m := image.NewRGBA(image.Rect(0, 0, 100, 100))
    m.Set(1, 1, color.RGBA{0x00, 0xFF, 0x00, 0xFF})
    file, _ := os.Create("new_image.gif")
    Encode(file, m)
}
<|endoftext|>


<commit_before>package contrail

import (
	"contrail-go-api"
	"contrail-go-api/types"
	"fmt"
	"testing"
)

func TestClient(t *testing.T) {
	client := contrail.NewClient("localhost", 8082)
	elements, err := client.List("project")
	if err != nil {
		t.Fatal(err)
	}
	if len(elements) < 1 {
		t.Error("Empty project list")
	}

	for _, element := range elements {
		obj, err := client.ReadListResult("project", &element)
		if obj == nil {
			t.Fatal(err)
		}

		var project *types.Project = obj.(*types.Project)
		networks, err := project.GetVirtualNetworks()
		if len(networks) < 1 {
			t.Error("Empty virtual-network list")
		}

		for _, network := range networks {
			iObj, err := client.ReadReference(
				"virtual-network", &network)
			if iObj == nil {
				t.Fatal(err)
			}
			net := iObj.(*types.VirtualNetwork)
			fmt.Println(net.GetName())
		}
	}
}

func TestCreate(t *testing.T) {
	client := contrail.NewClient("localhost", 8082)
	net := types.VirtualNetwork{}
	net.SetName("test")
	ipam, err := client.FindByName("network-ipam",
		"default-domain:default-project:default-network-ipam")
	if err != nil {
		t.Fatal(err)
	}
	subnets := types.VnSubnetsType{}
	subnets.AddIpamSubnets(
		&types.IpamSubnetType{
			Subnet: types.SubnetType{"10.0.0.0", 8}})
	net.AddNetworkIpam(ipam.(*types.NetworkIpam), subnets)
	err = client.Create(&net)
	if err != nil {
		t.Error(err)
	}
	if len(net.GetUuid()) == 0 {
		t.Error("No uuid assigned")
	}

	netPtr, err := client.FindByUuid("virtual-network", net.GetUuid())
	if err != nil {
		t.Error(err)
	} else {
		xnet := netPtr.(*types.VirtualNetwork)
		refs, err := xnet.GetNetworkIpamRefs()
		if err != nil {
			t.Error(err)
		} else if len(refs) > 0 {
			xnet.DeleteNetworkIpam(refs[0].Uuid)
			nsubnets := types.VnSubnetsType{}
			nsubnets.AddIpamSubnets(
				&types.IpamSubnetType{
					Subnet: types.SubnetType{
						"192.168.0.0", 16}})
			xnet.AddNetworkIpam(ipam.(*types.NetworkIpam), nsubnets)
			client.Update(xnet)
		} else {
			t.Error("Empty network-ipam reference list")
		}
	}

	err = client.Delete(&net)
	if err != nil {
		t.Error(err)
	}
}
<commit_msg>Add unit tests for property update and reference updates<commit_after>package contrail

import (
	"contrail-go-api"
	"contrail-go-api/types"
	"fmt"
	"testing"
)

func TestClient(t *testing.T) {
	client := contrail.NewClient("localhost", 8082)
	elements, err := client.List("project")
	if err != nil {
		t.Fatal(err)
	}
	if len(elements) < 1 {
		t.Error("Empty project list")
	}

	for _, element := range elements {
		obj, err := client.ReadListResult("project", &element)
		if obj == nil {
			t.Fatal(err)
		}

		var project *types.Project = obj.(*types.Project)
		networks, err := project.GetVirtualNetworks()
		if len(networks) < 1 {
			t.Error("Empty virtual-network list")
		}

		for _, network := range networks {
			iObj, err := client.ReadReference(
				"virtual-network", &network)
			if iObj == nil {
				t.Fatal(err)
			}
			net := iObj.(*types.VirtualNetwork)
			fmt.Println(net.GetName())
		}
	}
}

func TestCreate(t *testing.T) {
	client := contrail.NewClient("localhost", 8082)
	net := types.VirtualNetwork{}
	net.SetName("test")
	ipam, err := client.FindByName("network-ipam",
		"default-domain:default-project:default-network-ipam")
	if err != nil {
		t.Fatal(err)
	}
	subnets := types.VnSubnetsType{}
	subnets.AddIpamSubnets(
		&types.IpamSubnetType{
			Subnet: types.SubnetType{"10.0.0.0", 8}})
	net.AddNetworkIpam(ipam.(*types.NetworkIpam), subnets)
	err = client.Create(&net)
	if err != nil {
		t.Error(err)
	}
	if len(net.GetUuid()) == 0 {
		t.Error("No uuid assigned")
	}

	netPtr, err := client.FindByUuid("virtual-network", net.GetUuid())
	if err != nil {
		t.Error(err)
	} else {
		xnet := netPtr.(*types.VirtualNetwork)
		refs, err := xnet.GetNetworkIpamRefs()
		if err != nil {
			t.Error(err)
		} else if len(refs) > 0 {
			xattr := refs[0].Attr.(types.VnSubnetsType)
			if len(xattr.IpamSubnets) == 1 {
				isubnet := xattr.IpamSubnets[0]
				if isubnet.Subnet.IpPrefix != "10.0.0.0" ||
					isubnet.Subnet.IpPrefixLen != 8 {
					t.Errorf("Bad subnet %s/%d",
						isubnet.Subnet.IpPrefix,
						isubnet.Subnet.IpPrefixLen)
				}
			} else {
				t.Errorf("%d subnets", len(xattr.IpamSubnets))
			}
		} else {
			t.Error("Empty network-ipam reference list")
		}
	}

	err = client.Delete(&net)
	if err != nil {
		t.Error(err)
	}
}

func TestPropertyUpdate(t *testing.T) {
	client := contrail.NewClient("localhost", 8082)
	net := types.VirtualNetwork{}
	net.SetName("test")

	err := client.Create(&net)
	if err != nil {
		t.Error(err)
	}

	defer client.Delete(&net)

	props := net.GetVirtualNetworkProperties()
	if len(props.ForwardingMode) > 0 {
		t.Error(props.ForwardingMode)
	}
	props.ForwardingMode = "l2_l3"
	net.SetVirtualNetworkProperties(&props)
	err = client.Update(&net)
	if err != nil {
		t.Error(err)
	}

	obj, err := client.FindByUuid("virtual-network", net.GetUuid())
	if err != nil {
		t.Fatal(err)
	}
	netPtr := obj.(*types.VirtualNetwork)
	p2 := netPtr.GetVirtualNetworkProperties()
	if p2.ForwardingMode != "l2_l3" {
		t.Errorf("Expected: l2_l3 got: %s", p2.ForwardingMode)
	}
}

func TestReferenceUpdate(t *testing.T) {
	client := contrail.NewClient("localhost", 8082)
	net := types.VirtualNetwork{}
	net.SetName("test2")
	ipam, err := client.FindByName("network-ipam",
		"default-domain:default-project:default-network-ipam")
	if err != nil {
		t.Fatal(err)
	}
	subnets := types.VnSubnetsType{}
	subnets.AddIpamSubnets(
		&types.IpamSubnetType{
			Subnet: types.SubnetType{"10.0.0.0", 8}})
	net.AddNetworkIpam(ipam.(*types.NetworkIpam), subnets)
	err = client.Create(&net)
	if err != nil {
		t.Error(err)
	}

	defer client.Delete(&net)

	obj, err := client.FindByUuid("virtual-network", net.GetUuid())
	if err != nil {
		t.Fatal(err)
	}

	netPtr := obj.(*types.VirtualNetwork)
	refs, err := netPtr.GetNetworkIpamRefs()
	if err != nil {
		t.Error(err)
	} else if len(refs) > 0 {
		netPtr.DeleteNetworkIpam(refs[0].Uuid)
		nsubnets := types.VnSubnetsType{}
		nsubnets.AddIpamSubnets(
			&types.IpamSubnetType{
				Subnet: types.SubnetType{
					"192.168.0.0", 16}})
		netPtr.AddNetworkIpam(ipam.(*types.NetworkIpam), nsubnets)
		client.Update(netPtr)
	} else {
		t.Error("Empty network-ipam reference list")
	}

	obj, err = client.FindByUuid("virtual-network", net.GetUuid())
	if err != nil {
		t.Fatal(err)
	}
	netPtr = obj.(*types.VirtualNetwork)
	refs, err = netPtr.GetNetworkIpamRefs()
	if err != nil {
		t.Error(err)
	} else if len(refs) != 1 {
		t.Errorf("Expected: 1 reference, %d actual", len(refs))
	} else {
		xattr := refs[0].Attr.(types.VnSubnetsType)
		if len(xattr.IpamSubnets) == 1 {
			isubnet := xattr.IpamSubnets[0]
			if isubnet.Subnet.IpPrefix != "192.168.0.0" ||
				isubnet.Subnet.IpPrefixLen != 16 {
				t.Errorf("Bad subnet %s/%d",
					isubnet.Subnet.IpPrefix,
					isubnet.Subnet.IpPrefixLen)
			}
		} else {
			t.Errorf("%d subnets", len(xattr.IpamSubnets))
		}
	}

	netPtr.ClearNetworkIpam()
	client.Update(netPtr)

	obj, err = client.FindByUuid("virtual-network", net.GetUuid())
	if err != nil {
		t.Fatal(err)
	}
	netPtr = obj.(*types.VirtualNetwork)
	refs, err = netPtr.GetNetworkIpamRefs()
	if err != nil {
		t.Error(err)
	} else if len(refs) != 0 {
		t.Errorf("Expected: 1 reference, %d actual", len(refs))
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"

	"github.com/coreos/go-etcd/etcd"
	"github.com/miekg/dns"
)

func dnsSetup(cfg *Config, etc *etcd.Client) chan error {
	dns.HandleFunc(".", proxyServe)
	etc.CreateDir("dns", 0)
	exit := make(chan error, 1)

	go func() {
		exit <- dns.ListenAndServe("0.0.0.0:53", "tcp", nil)
	}()

	go func() {
		exit <- dns.ListenAndServe("0.0.0.0:53", "udp", nil)
	}()

	return exit
}

func proxyServe(w dns.ResponseWriter, req *dns.Msg) {
	q := req.Question[0]

	if req.MsgHdr.Response == true { // supposed responses sent to us are bogus
		fmt.Printf("DNS Query IS BOGUS %s %s from %s.\n", q.Name, dns.Type(q.Qtype).String(), w.RemoteAddr())
		return
	}

	fmt.Printf("DNS Query %s %s from %s.\n", q.Name, dns.Type(q.Qtype).String(), w.RemoteAddr())

	c := new(dns.Client)
	m, _, err := c.Exchange(req, "8.8.8.8:53")

	if err != nil {
		fmt.Println(err)
	} else {
		w.WriteMsg(m)
	}
}
<commit_msg>Renamed DNS main serve function<commit_after>package main

import (
	"fmt"

	"github.com/coreos/go-etcd/etcd"
	"github.com/miekg/dns"
)

func dnsSetup(cfg *Config, etc *etcd.Client) chan error {
	dns.HandleFunc(".", dnsQueryServe)
	etc.CreateDir("dns", 0)
	exit := make(chan error, 1)

	go func() {
		exit <- dns.ListenAndServe("0.0.0.0:53", "tcp", nil)
	}()

	go func() {
		exit <- dns.ListenAndServe("0.0.0.0:53", "udp", nil)
	}()

	return exit
}

func dnsQueryServe(w dns.ResponseWriter, req *dns.Msg) {
	q := req.Question[0]

	if req.MsgHdr.Response == true { // supposed responses sent to us are bogus
		fmt.Printf("DNS Query IS BOGUS %s %s from %s.\n", q.Name, dns.Type(q.Qtype).String(), w.RemoteAddr())
		return
	}

	fmt.Printf("DNS Query %s %s from %s.\n", q.Name, dns.Type(q.Qtype).String(), w.RemoteAddr())

	c := new(dns.Client)
	m, _, err := c.Exchange(req, "8.8.8.8:53")

	if err != nil {
		fmt.Println(err)
	} else {
		w.WriteMsg(m)
	}
}
<|endoftext|>


<commit_before>// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

/*
Package looli is a minimalist web framework for go

router usage
    router := looli.Default()

    v1 := router.Prefix("/v1")
    v1.Get("/a", func(c *looli.Context) {
        c.Status(200)
        c.String("hello world version1\n")
    })

    v2 := router.Prefix("/v2")
    v2.Get("/a", func(c *looli.Context) {
        c.Status(200)
        c.String("hello world version2\n")
    })

    router.Get("/a", func(c *looli.Context) {
        c.Status(200)
        c.String("hello world!\n")
    })
*/

package looli
<commit_msg>fix: doc<commit_after>// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

/*
Package looli is a minimalist web framework for go

router usage
    router := looli.Default()

    v1 := router.Prefix("/v1")
    v1.Get("/a", func(c *looli.Context) {
        c.Status(200)
        c.String("hello world version1\n")
    })

    v2 := router.Prefix("/v2")
    v2.Get("/a", func(c *looli.Context) {
        c.Status(200)
        c.String("hello world version2\n")
    })

    router.Get("/a", func(c *looli.Context) {
        c.Status(200)
        c.String("hello world!\n")
    })
*/
package looli
<|endoftext|>


<commit_before>// Copyright (c) 2017 Marc René Arns. All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

/*
  Package midi provides interfaces for reading and writing of MIDI messages.

  Since they are handled slightly different, this packages introduces the terminology of
  "live" MIDI reading/writing for dealing with MIDI messages as "over the wire" (in realtime)
  as opposed to smf MIDI reading/writing to Standard MIDI Files (SMF).

  However both variants can be used with io.Writer and io.Reader and can thus be "streamed".

  This package provides a Reader and Writer interface that is common to live and SMF MIDI handling.
  This should allow to easily develop transformations (e.g. quantization,
  filtering) that may be used in both cases.

  One package providing a unified access in both cases is the handler package for reading MIDI data.

    github.com/gomidi/midi/midihandler    (reading MIDI messages live or from SMF files)

  The core implementations can be found here:

    github.com/gomidi/midi/midireader (live reading)
    github.com/gomidi/midi/midiwriter (live writing)
    github.com/gomidi/midi/smf/smfreader   (SMF reading)
    github.com/gomidi/midi/smf/smfwriter   (SMF writing)
    github.com/gomidi/midi/smf/smfmodify   (SMF modification)

  The MIDI messages themselves that can be written or analyzed can be found here:

    github.com/gomidi/midi/midimessage/channel    (Channel Messages)
    github.com/gomidi/midi/midimessage/cc         (Control Change Messages)
    github.com/gomidi/midi/midimessage/meta       (Meta Messages)
    github.com/gomidi/midi/midimessage/realtime   (System Realtime Messages)
    github.com/gomidi/midi/midimessage/syscommon  (System Common messages)
    github.com/gomidi/midi/midimessage/sysex      (System Exclusive messages)

  Please keep in mind that that not all kinds of MIDI messages can be used in both scenarios.

  System Realtime and System Common Messages are restricted to "over the wire",
  while Meta Messages are restricted to SMF files. However System Realtime and System Common Messages
  can be saved inside a SMF file which the help of SysEx escaping (F7).

*/
package midi
<commit_msg>fix docs<commit_after>// Copyright (c) 2017 Marc René Arns. All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

/*
  Package midi provides interfaces for reading and writing of MIDI messages.

  Since they are handled slightly different, this packages introduces the terminology of
  "live" MIDI reading/writing for dealing with MIDI messages as "over the wire" (in realtime)
  as opposed to smf MIDI reading/writing to Standard MIDI Files (SMF).

  However both variants can be used with io.Writer and io.Reader and can thus be "streamed".

  This package provides a Reader and Writer interface that is common to live and SMF MIDI handling.
  This should allow to easily develop transformations (e.g. quantization,
  filtering) that may be used in both cases.

  One package providing a unified access in both cases is the handler package for reading MIDI data.

    github.com/gomidi/midi/midihandler    (reading MIDI messages live or from SMF files)

  The core implementations can be found here:

    github.com/gomidi/midi/midireader (live reading)
    github.com/gomidi/midi/midiwriter (live writing)
    github.com/gomidi/midi/smf/smfreader   (SMF reading)
    github.com/gomidi/midi/smf/smfwriter   (SMF writing)
    github.com/gomidi/midi/smf/smftrack    (SMF modification)

  The MIDI messages themselves that can be written or analyzed can be found here:

    github.com/gomidi/midi/midimessage/channel    (Channel Messages)
    github.com/gomidi/midi/midimessage/cc         (Control Change Messages)
    github.com/gomidi/midi/midimessage/meta       (Meta Messages)
    github.com/gomidi/midi/midimessage/realtime   (System Realtime Messages)
    github.com/gomidi/midi/midimessage/syscommon  (System Common messages)
    github.com/gomidi/midi/midimessage/sysex      (System Exclusive messages)

  Please keep in mind that that not all kinds of MIDI messages can be used in both scenarios.

  System Realtime and System Common Messages are restricted to "over the wire",
  while Meta Messages are restricted to SMF files. However System Realtime and System Common Messages
  can be saved inside a SMF file which the help of SysEx escaping (F7).

*/
package midi
<|endoftext|>


<commit_before>/*
Package cors is a handler for the Core (https://github.com/volatile/core).
It enables Cross-Origin Resource Sharing support.

Make sure to include the handler above any other handler that alter the response body.

Documentation about CORS:

- http://www.w3.org/TR/cors/

- https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

- http://www.html5rocks.com/en/tutorials/cors/

Usage

When using CORS (globally or locally), there is always a parameter of type OriginsMap.
It can contain a map of allowed origins and their specific options.

Use nil as OriginsMap to allow all headers, methods and origins.

	cors.Use(nil)

Use nil as origin's *Options to allow all headers and methods for this origin.

	cors.Use(cors.OriginsMap{
		"example.com": nil,
	})

Use AllOrigins as an OriginsMap key to set options for all origins.

	cors.Use(cors.OriginsMap{
		"example.com": nil, // All is allowed for this origin.
		cors.AllOrigins: &cors.Options{
			AllowedMethods: []string{"GET"}, // Only the GET method is allowed for the others.
		},
	})

Global

Use sets a global CORS configuration for all the handlers downstream.

	package main

	import (
		"fmt"

		"github.com/volatile/core"
		"github.com/volatile/cors"
	)

	func main() {
		cors.Use(nil)

		// All is allowed for the "/" path.
		core.Use(func(c *core.Context) {
			if c.Request.URL.Path == "/" {
				fmt.Fprint(c.ResponseWriter, "Hello, World!")
			}
		})

		// The previous CORS options are overwritten.
		cors.Use(cors.OriginsMap{
			cors.AllOrigins: &cors.Options{
				AllowedMethods: []string{"GET"},
			},
		})

		// Only the GET method is allowed for this handler.
		core.Use(func(c *core.Context) {
			fmt.Fprint(c.ResponseWriter, "Read only")
		})

		core.Run()
	}

Local

LocalUse can be used to set CORS locally, for a single handler.
The global CORS options (if used) are overwritten in this situation.

The last func parameter is called after the CORS headers are set, but only if it's not a preflight request (http://www.w3.org/TR/cors/#resource-preflight-requests).

	package main

	import (
		"fmt"
		"net/http"

		"github.com/volatile/core"
		"github.com/volatile/cors"
		"github.com/volatile/response"
	)

	func main() {
		// Global use
		cors.Use(nil)

		// Local use for the "/hook" path.
		core.Use(func(c *core.Context) {
			if c.Request.URL.Path == "/hook" {
				cors.LocalUse(c, cors.OriginsMap{
					cors.AllOrigins: &cors.Options{AllowedMethods: []string{"GET"}},
				}, func() {
					response.Status(c, http.StatusOK)
				})
			}
			c.Next()
		})

		// No local CORS are set, so the global CORS options are used.
		core.Use(func(c *core.Context) {
			fmt.Fprint(c.ResponseWriter, "Hello, World!")
		})

		core.Run()
	}
*/
package cors
<commit_msg>Update doc<commit_after>/*
Package cors is a handler for the Core (https://github.com/volatile/core).
It enables Cross-Origin Resource Sharing support.

Make sure to include the handler above any other handler that alter the response body.

Documentation about CORS:

- http://www.w3.org/TR/cors/

- https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

- http://www.html5rocks.com/en/tutorials/cors/

Installation

In the terminal:

	$ go get github.com/volatile/cors

Usage

When using CORS (globally or locally), there is always a parameter of type OriginsMap.
It can contain a map of allowed origins and their specific options.

Use nil as OriginsMap to allow all headers, methods and origins.

	cors.Use(nil)

Use nil as origin's *Options to allow all headers and methods for this origin.

	cors.Use(cors.OriginsMap{
		"example.com": nil,
	})

Use AllOrigins as an OriginsMap key to set options for all origins.

	cors.Use(cors.OriginsMap{
		"example.com": nil, // All is allowed for this origin.
		cors.AllOrigins: &cors.Options{
			AllowedMethods: []string{"GET"}, // Only the GET method is allowed for the others.
		},
	})

Global

Use sets a global CORS configuration for all the handlers downstream.

	package main

	import (
		"fmt"

		"github.com/volatile/core"
		"github.com/volatile/cors"
	)

	func main() {
		cors.Use(nil)

		// All is allowed for the "/" path.
		core.Use(func(c *core.Context) {
			if c.Request.URL.Path == "/" {
				fmt.Fprint(c.ResponseWriter, "Hello, World!")
			}
		})

		// The previous CORS options are overwritten.
		cors.Use(cors.OriginsMap{
			cors.AllOrigins: &cors.Options{
				AllowedMethods: []string{"GET"},
			},
		})

		// Only the GET method is allowed for this handler.
		core.Use(func(c *core.Context) {
			fmt.Fprint(c.ResponseWriter, "Read only")
		})

		core.Run()
	}

Local

LocalUse can be used to set CORS locally, for a single handler.
The global CORS options (if used) are overwritten in this situation.

The last func parameter is called after the CORS headers are set, but only if it's not a preflight request (http://www.w3.org/TR/cors/#resource-preflight-requests).

	package main

	import (
		"fmt"
		"net/http"

		"github.com/volatile/core"
		"github.com/volatile/cors"
		"github.com/volatile/response"
	)

	func main() {
		// Global use
		cors.Use(nil)

		// Local use for the "/hook" path.
		core.Use(func(c *core.Context) {
			if c.Request.URL.Path == "/hook" {
				cors.LocalUse(c, cors.OriginsMap{
					cors.AllOrigins: &cors.Options{AllowedMethods: []string{"GET"}},
				}, func() {
					response.Status(c, http.StatusOK)
				})
			}
			c.Next()
		})

		// No local CORS are set, so the global CORS options are used.
		core.Use(func(c *core.Context) {
			fmt.Fprint(c.ResponseWriter, "Hello, World!")
		})

		core.Run()
	}
*/
package cors
<|endoftext|>


<commit_before>/*
Package cli provides a framework to build command line applications in Go with most of the burden of arguments parsing and validation
placed on the framework instead of the user.

Basics

You start by creating an application by passing a name and a description:

	cp = cli.App("cp", "Copy files around")

To attach the code to execute when the app is launched, assign a function to the Action field:
	cp.Action = func() {
		fmt.Printf("Hello world\n")
	}

Finally, in your main func, call Run on the app:

	cp.Run(os.Args)

Options

To add a (global) option, call one of the (String[s]|Int[s]|Bool)Opt methods on the app:

	recursive := cp.BoolOpt("R recursive", false, "recursively copy the src to dst", nil)

* The first argument is a space seperated list of names for the option without the dashes
* The second parameter is the default value for the option
* The third parameter is the option description, as will be shown in the help messages
* The last parameter is an optional OptExtra struct.
For the time being there is one field, EnvVar where you could set a space separated list of environment
variables to be used to initialize the option's value

The result is a pointer to a value that will be populated after parsing the command line arguments.
You can access the values in the Action func.

In the command line, mow.cli accepts the following syntaxes

* For boolean options:

	-f : a single dash for the one letter names
	--force :  double dash for longer option names
	-it : mow.cli supports option folding, this is equivalent to: -i -t

* For string, int options:

	-e=value : single dash for one letter names, equal sign followed by the value
	-e value : single dash for one letter names, space followed by the value
	-Ivalue : single dash for one letter names immediately followed by the value
	--extra=value : double dash for longer option names, equal sign followed by the value
	--extra value : double dash for longer option names, space followed by the value

* For slice options (StringsOpt, IntsOpt): repeat the option to accumulate the values in the resulting slice:

	-e PATH:/bin -e PATH:/usr/bin : resulting slice contains ["/bin", "/usr/bin"]

Arguments

To accept arguments, you need to explicitly declare them by calling one of the (String[s]|Int[s]|Bool)Arg methods on the app:

	src := cp.StringArg("SRC", "", "the file to copy", nil)
	dst := cp.StringArg("DST", "", "the destination", nil)

* The first argument is the argument name as will be shown in the help messages
* The second parameter is the default value for the argument
* The third parameter is the argument description, as will be shown in the help messages
* The last parameter is an optional ArgExtra struct.
For the time being there is one field, EnvVar where you could set a space separated list of environment
variables to be used to initialize the argument's value

The result is a pointer to a value that will be populated after parsing the command line arguments.
You can access the values in the Action func.

Commands

mow.cli supports nesting commands and sub commands.
Declare a top level command by calling the Command func on the app struct, and a sub command by calling
the Command func on the command struct:

	docker := cli.App("docker", "A self-sufficient runtime for linux containers")

	docker.Command("run", "Run a command in a new container", func(cmd *cli.Cmd) {
		// initialize the run command here
	})

* The first argument is the command name, as will be shown in the help messages and as will need to be input by the user in the command line to call the command
* The second argument is the command description as will be shown in the help messages
* The third argument is a CmdInitializer, a function that receives a pointer to a Cmd struct representing the command.
In this function, you can add options and arguments by calling the same methods as you would with an app struct (BoolOpt, StringArg, ...).
You would also assign a function to the Action field of the Cmd struct for it to be executed when the command is invoked.

	docker.Command("run", "Run a command in a new container", func(cmd *cli.Cmd) {
		detached := cmd.BoolOpt("d detach", false, "Detached mode: run the container in the background and print the new container ID", nil)
		memory := cmd.StringOpt("m memory", "", "Memory limit (format: <number><optional unit>, where unit = b, k, m or g)", nil)

		image := cmd.StringArg("IMAGE", "", "", nil)

		cmd.Action = func() {
			if *detached {
				//do something
			}
			runContainer(*image, *detached, *memory)
		}
	})

You can also add sub commands by calling Command on the Cmd struct:

	bzk.Command("job", "actions on jobs", func(cmd *cli.Cmd) {
		cmd.Command("list", "list jobs", listJobs)
		cmd.Command("start", "start a new job", startJob)
		cmd.Command("log", "show a job log", nil)
	})

This could go on to any depth if need be.

Spec

An app or command's call syntax can be customized using spec strings.
This can be useful to indicate that an argument is optional for example, or that 2 options are mutually exclusive.

You can set a spec string on:

* The app: to configure the syntax for global options and arguments
* A command: to configure the syntax for that command's options and arguments

In both cases, a spec string is assigned to the Spec field:

	cp := cli.App("cp", "Copy files around")
	cp.Spec = "[-R [-H | -L | -P]]"

And:

	docker := cli.App("docker", "A self-sufficient runtime for linux containers")
	docker.Command("run", "Run a command in a new container", func(cmd *cli.Cmd) {
		cmd.Spec = "[-d|--rm] IMAGE [COMMAND [ARG...]]"
		:
		:
	}

The spec syntax is mostly based on the conventions used in POSIX command line apps help messages and man pages:

Options

You can use both short and long option names in spec strings:
	x.Spec="-f"
And:
	x.Spec="--force"

In both cases, we required that the f or force flag be set

Any option you reference in a spec string MUST be explicitly declared, otherwise mow.cli will panic:

	x.BoolOpt("f force", ...)

Arguments

Arguments are all-uppercased words:
	x.Spec="SRC DST"
This spec string will force the user to pass exactly 2 arguments, SRC and DST

Any argument you reference in a spec string MUST be explicitly declared, otherwise mow.cli will panic:

	x.StringArg("SRC", ...)
	x.StringArg("DST", ...)

Ordering

The order of the elements in a spec string is respected and enforced when parsing the command line arguments:
	x.Spec = "-f SRC DST"

Optionality

You can mark iterms as optional in a spec string by enclosing them in squqre brackets :[...]
	x.Spec = "[-x]"

Choice

You can use the | operator to indicate a choice between two or more items
	x.Spec = "--rm | --daemon"
	x.Spec = "-H | -L | -P"
	x.Spec = "-t | DST"

Repetition

You can use the ... postfix operator to mark an element as repeatable:
	x.Spec="SRC..."
	x.Spec="-e..."

Grouping

You can group items using parenthesis. This is useful in combination with the choice and repetition operators (| and ...):
	x.Spec = "(-e COMMAND)... | (-x|-y)"
The parenthesis in the example above serve to mark that it is the sequence of a -e flag followed by an argument that is repeatable, and that
all that is mutually exclusive to a choice betwwen -x and -y options.

Option group

This is a shortcut to declare a choice between multiple options:
	x.Spec = "-abcd"
Is equivalent to
	x.Spec = "-a | -b | -c | -d"

All options

Another shortcut:
	x.Spec = "[OPTIONS]"
This is a special syntax (the square brackets are not for marking an optional item, and the uppercased word is not for an argument).
This is equivalent to a repeatable choice between all the available options.
For example, if an app or a command declares 4 options a, b, c and d, [OPTIONS] is equivalent to
	x.Spec = "[-a | -b | -c | -d]..."

Here's the EBNF grammar for the Specs language:

	spec         -> sequence
	sequence     -> choice*
	req_sequence -> choice+
	choice       -> atom ('|' atom)*
	atom         -> (shortOpt | longOpt | optSeq | allOpts | group | optional) rep?
	shortOp      -> '-' [A-Za-z]
	longOpt      -> '--' [A-Za-z][A-Za-z0-9]*
	optSeq       -> '-' [A-Za-z]+
	allOpts      -> '[OPTIONS]'
	group        -> '(' req_sequence ')'
	optional     -> '[' req_sequence ']'
	rep          -> '...'

And that's it for the spec language.
You can combine these few building blocks in any way you want (while respecting the grammar above) to construct sophisticated validation constraints
(don't go too wild though).

Behind the scenes, mow.cli parses the spec string and constructs a finite state machine to be used to parse the command line arguments.
mow.cli also handles backtracking, and so it can handle tricky cases, or what I like to call "the cp test"
	cp SRC... DST
Without backtracking, this deceptively simple spec string cannot be parsed correctly.
For instance, docopt can't handle this case, whereas mow.cli does.

Default spec

By default, and unless a spec string is set by the user, mow.cli auto-generates one for the app and every command using this logic:

* Start with an empty spec string
* If at least one option was declared, append "[OPTIONS]" to the spec string
* For every declared argument, append it, in the order of declaration, to the spec string

For example, given this command delcaration:
	docker.Command("run", "Run a command in a new container", func(cmd *cli.Cmd) {
		detached := cmd.BoolOpt("d detach", false, "Detached mode: run the container in the background and print the new container ID", nil)
		memory := cmd.StringOpt("m memory", "", "Memory limit (format: <number><optional unit>, where unit = b, k, m or g)", nil)

		image := cmd.StringArg("IMAGE", "", "", nil)
		args := cmd.StringsArg("ARG", "", "", nil)
	})
The auto-generated spec string would be:
	[OPTIONS] IMAGE ARG

Which should suffice for simple cases. If not, the spec string has to be set explicitly.
*/
package cli
<commit_msg>Fix formatting issues in the package godoc<commit_after>/*
Package cli provides a framework to build command line applications in Go with most of the burden of arguments parsing and validation
placed on the framework instead of the user.

Basics

You start by creating an application by passing a name and a description:

	cp = cli.App("cp", "Copy files around")

To attach the code to execute when the app is launched, assign a function to the Action field:
	cp.Action = func() {
		fmt.Printf("Hello world\n")
	}

Finally, in your main func, call Run on the app:

	cp.Run(os.Args)

Options

To add a (global) option, call one of the (String[s]|Int[s]|Bool)Opt methods on the app:

	recursive := cp.BoolOpt("R recursive", false, "recursively copy the src to dst", nil)

* The first argument is a space seperated list of names for the option without the dashes

* The second parameter is the default value for the option

* The third parameter is the option description, as will be shown in the help messages

* The last parameter is an optional OptExtra struct.
For the time being there is one field, EnvVar where you could set a space separated list of environment
variables to be used to initialize the option's value

The result is a pointer to a value that will be populated after parsing the command line arguments.
You can access the values in the Action func.

In the command line, mow.cli accepts the following syntaxes

* For boolean options:

	-f : a single dash for the one letter names
	--force :  double dash for longer option names
	-it : mow.cli supports option folding, this is equivalent to: -i -t

* For string, int options:

	-e=value : single dash for one letter names, equal sign followed by the value
	-e value : single dash for one letter names, space followed by the value
	-Ivalue : single dash for one letter names immediately followed by the value
	--extra=value : double dash for longer option names, equal sign followed by the value
	--extra value : double dash for longer option names, space followed by the value

* For slice options (StringsOpt, IntsOpt): repeat the option to accumulate the values in the resulting slice:

	-e PATH:/bin -e PATH:/usr/bin : resulting slice contains ["/bin", "/usr/bin"]

Arguments

To accept arguments, you need to explicitly declare them by calling one of the (String[s]|Int[s]|Bool)Arg methods on the app:

	src := cp.StringArg("SRC", "", "the file to copy", nil)
	dst := cp.StringArg("DST", "", "the destination", nil)

* The first argument is the argument name as will be shown in the help messages

* The second parameter is the default value for the argument

* The third parameter is the argument description, as will be shown in the help messages

* The last parameter is an optional ArgExtra struct.
For the time being there is one field, EnvVar where you could set a space separated list of environment
variables to be used to initialize the argument's value

The result is a pointer to a value that will be populated after parsing the command line arguments.
You can access the values in the Action func.

Commands

mow.cli supports nesting commands and sub commands.
Declare a top level command by calling the Command func on the app struct, and a sub command by calling
the Command func on the command struct:

	docker := cli.App("docker", "A self-sufficient runtime for linux containers")

	docker.Command("run", "Run a command in a new container", func(cmd *cli.Cmd) {
		// initialize the run command here
	})

* The first argument is the command name, as will be shown in the help messages and as will need to be input by the user in the command line to call the command

* The second argument is the command description as will be shown in the help messages

* The third argument is a CmdInitializer, a function that receives a pointer to a Cmd struct representing the command.
In this function, you can add options and arguments by calling the same methods as you would with an app struct (BoolOpt, StringArg, ...).
You would also assign a function to the Action field of the Cmd struct for it to be executed when the command is invoked.

	docker.Command("run", "Run a command in a new container", func(cmd *cli.Cmd) {
		detached := cmd.BoolOpt("d detach", false, "Detached mode: run the container in the background and print the new container ID", nil)
		memory := cmd.StringOpt("m memory", "", "Memory limit (format: <number><optional unit>, where unit = b, k, m or g)", nil)

		image := cmd.StringArg("IMAGE", "", "", nil)

		cmd.Action = func() {
			if *detached {
				//do something
			}
			runContainer(*image, *detached, *memory)
		}
	})

You can also add sub commands by calling Command on the Cmd struct:

	bzk.Command("job", "actions on jobs", func(cmd *cli.Cmd) {
		cmd.Command("list", "list jobs", listJobs)
		cmd.Command("start", "start a new job", startJob)
		cmd.Command("log", "show a job log", nil)
	})

This could go on to any depth if need be.

Spec

An app or command's call syntax can be customized using spec strings.
This can be useful to indicate that an argument is optional for example, or that 2 options are mutually exclusive.

You can set a spec string on:

* The app: to configure the syntax for global options and arguments

* A command: to configure the syntax for that command's options and arguments

In both cases, a spec string is assigned to the Spec field:

	cp := cli.App("cp", "Copy files around")
	cp.Spec = "[-R [-H | -L | -P]]"

And:

	docker := cli.App("docker", "A self-sufficient runtime for linux containers")
	docker.Command("run", "Run a command in a new container", func(cmd *cli.Cmd) {
		cmd.Spec = "[-d|--rm] IMAGE [COMMAND [ARG...]]"
		:
		:
	}

The spec syntax is mostly based on the conventions used in POSIX command line apps help messages and man pages:

Options

You can use both short and long option names in spec strings:
	x.Spec="-f"
And:
	x.Spec="--force"

In both cases, we required that the f or force flag be set

Any option you reference in a spec string MUST be explicitly declared, otherwise mow.cli will panic:

	x.BoolOpt("f force", ...)

Arguments

Arguments are all-uppercased words:
	x.Spec="SRC DST"
This spec string will force the user to pass exactly 2 arguments, SRC and DST

Any argument you reference in a spec string MUST be explicitly declared, otherwise mow.cli will panic:

	x.StringArg("SRC", ...)
	x.StringArg("DST", ...)

Ordering

The order of the elements in a spec string is respected and enforced when parsing the command line arguments:
	x.Spec = "-f SRC DST"

Optionality

You can mark iterms as optional in a spec string by enclosing them in squqre brackets :[...]
	x.Spec = "[-x]"

Choice

You can use the | operator to indicate a choice between two or more items
	x.Spec = "--rm | --daemon"
	x.Spec = "-H | -L | -P"
	x.Spec = "-t | DST"

Repetition

You can use the ... postfix operator to mark an element as repeatable:
	x.Spec="SRC..."
	x.Spec="-e..."

Grouping

You can group items using parenthesis. This is useful in combination with the choice and repetition operators (| and ...):
	x.Spec = "(-e COMMAND)... | (-x|-y)"
The parenthesis in the example above serve to mark that it is the sequence of a -e flag followed by an argument that is repeatable, and that
all that is mutually exclusive to a choice betwwen -x and -y options.

Option group

This is a shortcut to declare a choice between multiple options:
	x.Spec = "-abcd"
Is equivalent to
	x.Spec = "-a | -b | -c | -d"

All options

Another shortcut:
	x.Spec = "[OPTIONS]"
This is a special syntax (the square brackets are not for marking an optional item, and the uppercased word is not for an argument).
This is equivalent to a repeatable choice between all the available options.
For example, if an app or a command declares 4 options a, b, c and d, [OPTIONS] is equivalent to
	x.Spec = "[-a | -b | -c | -d]..."

Here's the EBNF grammar for the Specs language:

	spec         -> sequence
	sequence     -> choice*
	req_sequence -> choice+
	choice       -> atom ('|' atom)*
	atom         -> (shortOpt | longOpt | optSeq | allOpts | group | optional) rep?
	shortOp      -> '-' [A-Za-z]
	longOpt      -> '--' [A-Za-z][A-Za-z0-9]*
	optSeq       -> '-' [A-Za-z]+
	allOpts      -> '[OPTIONS]'
	group        -> '(' req_sequence ')'
	optional     -> '[' req_sequence ']'
	rep          -> '...'

And that's it for the spec language.
You can combine these few building blocks in any way you want (while respecting the grammar above) to construct sophisticated validation constraints
(don't go too wild though).

Behind the scenes, mow.cli parses the spec string and constructs a finite state machine to be used to parse the command line arguments.
mow.cli also handles backtracking, and so it can handle tricky cases, or what I like to call "the cp test"
	cp SRC... DST
Without backtracking, this deceptively simple spec string cannot be parsed correctly.
For instance, docopt can't handle this case, whereas mow.cli does.

Default spec

By default, and unless a spec string is set by the user, mow.cli auto-generates one for the app and every command using this logic:

* Start with an empty spec string

* If at least one option was declared, append "[OPTIONS]" to the spec string

* For every declared argument, append it, in the order of declaration, to the spec string

For example, given this command delcaration:
	docker.Command("run", "Run a command in a new container", func(cmd *cli.Cmd) {
		detached := cmd.BoolOpt("d detach", false, "Detached mode: run the container in the background and print the new container ID", nil)
		memory := cmd.StringOpt("m memory", "", "Memory limit (format: <number><optional unit>, where unit = b, k, m or g)", nil)

		image := cmd.StringArg("IMAGE", "", "", nil)
		args := cmd.StringsArg("ARG", "", "", nil)
	})
The auto-generated spec string would be:
	[OPTIONS] IMAGE ARG

Which should suffice for simple cases. If not, the spec string has to be set explicitly.
*/
package cli
<|endoftext|>


<commit_before>/*
Package log5go is a simple, powerful logging framework for Go, loosely based on Java's log4j.
Loggers support log4j's basic log levels out of the box: TRACE, DEBUG, INFO, WARN, ERROR,
and FATAL, but additional levels can be integrated into the framework while still respecting
the level hierarchy. log5go can log to the console or to one or more files and supports
log file archiving and rotation.

Basics

Loggers are configured using a builder pattern starting with NewLog(LogLevel) and
terminating either with Build() or BuildAndRegister(string). The former simply constructs a
new logger and hands it back to the caller. The latter registers the logger internally
using the caller's source path and supplied key. This results in package-safe loggers
that can be statically retrieved in other parts of the package using GetLog(string).

Examples

The following example creates a file logger and registers it with the name "db":

  log, err := log5go.Log(log5go.LogDebug).ToFile("/var/log", "myprog_db.log").Register("db")

All package local code will be able to retrieve the same logger by calling:

  log, err := log5go.GetLog("db")

This allows logging to be unobtrusive in code, since any package-local code can easily
obtain the desired logger without the need to create a global variable.

The following example creates a file logger with a log rotation scheme:

  log, err := log5go.Log(log5go.LogAll).ToFile("/var/log", "myprog.log").WithRotation(log5go.RollDaily, 7).Build()

In this example, the logger will archive the log file daily at midnight, maintaining a maximum
of 7 archived log files. (A timestamp is appended to the name of each log file and an attempt is
made to delete the file that was created 8 days ago.)
*/
package log5go

// Package version info
const VERSION = "0.9.0"
const MAJOR_VERSION = 0
const MINOR_VERSION = 9
const PATCH_VERSION = 0
<commit_msg>custom string formatting<commit_after>/*
Package log5go is a simple, powerful logging framework for Go, loosely based on Java's log4j.
Loggers support log4j's basic log levels out of the box: TRACE, DEBUG, INFO, WARN, ERROR,
and FATAL, but additional levels can be integrated into the framework while still respecting
the level hierarchy. log5go can log to the console or to one or more files and supports
log file archiving and rotation.

Basics

Loggers are configured using a builder pattern starting with NewLog(LogLevel) and
terminating either with Build() or BuildAndRegister(string). The former simply constructs a
new logger and hands it back to the caller. The latter registers the logger internally
using the caller's source path and supplied key. This results in package-safe loggers
that can be statically retrieved in other parts of the package using GetLog(string).

Examples

The following example creates a file logger and registers it with the name "db":

  log, err := log5go.Log(log5go.LogDebug).ToFile("/var/log", "myprog_db.log").Register("db")

All package local code will be able to retrieve the same logger by calling:

  log, err := log5go.GetLog("db")

This allows logging to be unobtrusive in code, since any package-local code can easily
obtain the desired logger without the need to create a global variable.

The following example creates a file logger with a log rotation scheme:

  log, err := log5go.Log(log5go.LogAll).ToFile("/var/log", "myprog.log").WithRotation(log5go.RollDaily, 7).Build()

In this example, the logger will archive the log file daily at midnight, maintaining a maximum
of 7 archived log files. (A timestamp is appended to the name of each log file and an attempt is
made to delete the file that was created 8 days ago.)
*/
package log5go

// Package version info
const VERSION = "0.10.0"
const MAJOR_VERSION = 0
const MINOR_VERSION = 10
const PATCH_VERSION = 0
<|endoftext|>


<commit_before>// Copyright (c) 2011 CZ.NIC z.s.p.o. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// blame: jnml, labs.nic.cz

// Golex is a lex/flex like (not fully POSIX lex compatible) utility.
// It renders .l formated data (http://flex.sourceforge.net/manual/Format.html#Format) to Go source code.
// The .l data can come from a file named in a command line argument.
// If no non-opt args are given, golex reads stdin.
//
// Options:
//	-DFA            print the DFA to stdout and quit
//	-nodfaopt		disable DFA optimization - don't use this for production code
//	-o fname        write to file `fname`, default is `lex.yy.go`
//	-t              write to stdout
//	-v              write some scanner statistics to stderr
//	-32bit          assume unicode rune lexer (partially implemented, disabled)
//
// Golex output is not pretty formated, use the standard tool:
//
//	    $ golex -t file.l | gofmt > file.go
//	or
//	    $ golex -o file.go file.l && gofmt -w file.go
//
// Missing/differing functionality of the current renderer (compared to flex):
//	- No runtime tokenizer package/environment
//	  (but the freedom to have/write any fitting one's specific task(s)).
//	- The generated FSM picks the rules in the order of their appearance in the .l source,
//	  but "flex picks the rule that matches the most text".
//	- No back step. For patterns `a` and `abc` the text `abxy` doesn't match anything.
//	  Flex would match pattern `a` after seeing `x` and it's next scan will start at `b`.
//	  The lex.L FSM has all the data to properly render this functionality,
//	  it's only this tool that doesn't implement it.
//	- And probably more.
// Further limitations on the .l source are listed in the cznic/lex package godocs.
//
// A simple golex program example (make example1 && ./example1):
//
//	%{
//	package main
//
//	import (
//	    "bufio"
//	    "fmt"
//	    "os"
//	)
//
//	var (
//	    src      = bufio.NewReader(os.Stdin)
//	    buf      []byte
//	    current  byte
//	)
//
//	func getc() byte {
//	    if current != 0 {
//	        buf = append(buf, current)
//	    }
//	    current = 0
//	    if b, err := src.ReadByte(); err == nil {
//	        current = b
//	    }
//	    return current
//	}
//
//	func main() { // This left brace is closed by *1
//	    c := getc() // init
//	%}
//
//	%yyc c
//	%yyn c = getc()
//
//	D   [0-9]+
//
//	%%
//	    buf = buf[:0]   // Code before the first rule is executed before every scan cycle (state 0 action)
//
//	[ \t\n\r]+         // Ignore
//
//	{D}                 fmt.Printf("int %q\n", buf)
//
//	{D}\.{D}?|\.{D}     fmt.Printf("float %q\n", buf)
//
//	\0                  return // Exit on EOF or any other error
//
//	.                   fmt.Printf("%q\n", buf) // Printout any other unrecognized stuff
//
//	%%
//	    // The rendered scanner enters top of the user code section when
//	    // lexem recongition fails. In this example it should never happen.
//	    panic("scanner internal error")
//
//	} // *1 this right brace
package documentation
<commit_msg>Documented %yyx macros.<commit_after>// Copyright (c) 2011 CZ.NIC z.s.p.o. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// blame: jnml, labs.nic.cz

// Golex is a lex/flex like (not fully POSIX lex compatible) utility.
// It renders .l formated data (http://flex.sourceforge.net/manual/Format.html#Format) to Go source code.
// The .l data can come from a file named in a command line argument.
// If no non-opt args are given, golex reads stdin.
//
// Options:
//	-DFA            print the DFA to stdout and quit
//	-nodfaopt       disable DFA optimization - don't use this for production code
//	-o fname        write to file `fname`, default is `lex.yy.go`
//	-t              write to stdout
//	-v              write some scanner statistics to stderr
//	-32bit          assume unicode rune lexer (partially implemented, disabled)
//
// Golex output is not pretty formated, use the standard tool:
//
//	    $ golex -t file.l | gofmt > file.go
//	or
//	    $ golex -o file.go file.l && gofmt -w file.go
//
// Missing/differing functionality of the current renderer (compared to flex):
//	- No runtime tokenizer package/environment
//	  (but the freedom to have/write any fitting one's specific task(s)).
//	- The generated FSM picks the rules in the order of their appearance in the .l source,
//	  but "flex picks the rule that matches the most text".
//	- No back step. For patterns `a` and `abc` the text `abxy` doesn't match anything.
//	  Flex would match pattern `a` after seeing `x` and it's next scan will start at `b`.
//	  The lex.L FSM has all the data to properly render this functionality,
//	  it's only this tool that doesn't implement it.
//	- And probably more.
// Further limitations on the .l source are listed in the cznic/lex package godocs.
//
// A simple golex program example (make example1 && ./example1):
//
//	%{
//	package main
//
//	import (
//	    "bufio"
//	    "fmt"
//	    "os"
//	)
//
//	var (
//	    src      = bufio.NewReader(os.Stdin)
//	    buf      []byte
//	    current  byte
//	)
//
//	func getc() byte {
//	    if current != 0 {
//	        buf = append(buf, current)
//	    }
//	    current = 0
//	    if b, err := src.ReadByte(); err == nil {
//	        current = b
//	    }
//	    return current
//	}
//
//	//    %yyc is a "macro" to access the "current" character.
//	//
//	//    %yyn is a "macro" to move to the "next" character.
//	//
//	//    %yyb is a "macro" to return the begining-of-line status (a bool typed value).
//	//        It is used for patterns like `^re`.
//	//        Example: %yyb prev == 0 || prev == '\n'
//	//
//	//    %yyt is a "macro" to return the top/current start condition (an int typed value).
//	//        It is used when there are patterns with conditions like `<cond>re`.
//	//        Example: %yyt startCond
//
//	func main() { // This left brace is closed by *1
//	    c := getc() // init
//	%}
//
//	%yyc c
//	%yyn c = getc()
//
//	D   [0-9]+
//
//	%%
//	    buf = buf[:0]   // Code before the first rule is executed before every scan cycle (state 0 action)
//
//	[ \t\n\r]+          // Ignore whitespace
//
//	{D}                 fmt.Printf("int %q\n", buf)
//
//	{D}\.{D}?|\.{D}     fmt.Printf("float %q\n", buf)
//
//	\0                  return // Exit on EOF or any other error
//
//	.                   fmt.Printf("%q\n", buf) // Printout any other unrecognized stuff
//
//	%%
//	    // The rendered scanner enters top of the user code section when
//	    // lexem recongition fails. In this example it should never happen.
//	    panic("scanner internal error")
//
//	} // *1 this right brace
package documentation
<|endoftext|>


<commit_before>// Hanayo is the Ripple front-end web server.
package main

// version is the current version of hanayo
const version = "v1.4.0"
<commit_msg>⬆ v1.6.0 ⬆<commit_after>// Hanayo is the Ripple front-end web server.
package main

// version is the current version of hanayo
const version = "v1.6.0"
<|endoftext|>


<commit_before>/*
secfileshare is an experimental tool to share files securely.

What is it?
The internet is rife with commercial and other insecure file sharing solutions.
secfileshare is trying to address this by implementing client side crypto while remaining easy to use.

It consists of two programs.
A client side program that encrypts and uploads the blob and a server that stores said blob.
Once a client finishes uploading the blob it'll receive a link from the server that can be used to retrieve the blob at a later time.

Note: The server side currently does not do any form of authentication and downloads blobs fully into memory first.
This obviously can be abused and crashed etc.
Do realize that at this time this software is considered experimental.

Why do we need this?
Hackers, social media, governments etc are increasingly infringing on our privacy and being able to safely and securely share information with others is vital in this day and age.
Closed source crypto solutions are bad since they can not be audited and verified by 3rd parties.
Commercial entities have proven to be unscrupulous and can not be trusted.

How does it work?
The tool leverages the ideas of the outstanding NaCl (http://nacl.cr.yp.to/) crypto suite.
It uses only free, not patented algorithms that were developed in academia that are seemingly untainted by government influence.
All messages are encrypted using NaCl boxes that use Curve25519, XSalsa20 and Poly1305 for encryption and public-key authenticators.
Additionally the mcrypt package (https://github.com/marcopeereboom/mcrypt) adds public-key signatures.

secfileshare builds on top of this and adds an ephemeral shared secret that encrypts the file that will be shared.
The ephemeral shared secret is then encrypted by the originator's private key and N recipients public keys.
The resulting blob does not contain any identifiable information regarding the originator or the recipients.

How do I start using it?
Install Go! http://golang.org/doc/install

Install secfileshare
go get github.com/marcopeereboom/secfileshare.git

Run secfileshare without any parameters.
This will create your keys.

Note that secfileshare uses HTTPS URLs to distinguish if it is dealing with files or servers.

The process of sharing files is simple.
1. Obtain the public key from the party you wish to share with.
2. Upload file to server using the recipient public key.
3. Share the link and your public-key with the recipient.

Examples

File to Server
Encrypt and upload a file to a single recipient
secfileshare -in filename -out https://a.b.c:12345 RecipientPublicKey

Encrypt and upload a file to a multiple recipients
secfileshare -in filename -out https://a.b.c:12345 Recipient1PublicKey Recipient2PublicKey Recipient3PublicKey

Encrypt and upload a file to a single recipient with an optional description
secfileshare -d "you wanted this" -in filename -out https://a.b.c:12345 RecipientPublicKey

Note that if you want to be able to decrypt the blob yourself that you must provide your public-key as well.

Server to File
Download and decrypt a single file
secfileshare https://a.b.c:12345/887123051

Download and decrypt multiple files
secfileshare https://a.b.c:12345/887123051 https://a.b.c:12345/887123052 https://a.b.c:12345/887123053

Download and decrypt a single file to a specific filename
secfileshare -out myfile https://a.b.c:12345/887123051

Do read the tool's help as well since it explains the -out parameter that is used to manipulate the out filenames.

File to File
secfileshare -in filename -out sharefilename -mode encrypt Recipient1PublicKey

To-Do:
	* Switch to binary protocol
	* Chunk data instead so that we don't have to do everything everything in memory
	* Add authentication to both sides
	* Add MIME handlers in client so that it can auto launch viewers for downloaded files
	* Add a client GUI
	* Add server management using HTTPS
	* Figure out auto-PKI
*/
package main
<commit_msg>somewhat better formatting<commit_after>/*
secfileshare is an experimental tool to share files securely.

What is it?

The internet is rife with commercial and other insecure file sharing solutions.
secfileshare is trying to address this by implementing client side crypto while remaining easy to use.

It consists of two programs.
A client side program that encrypts and uploads the blob and a server that stores said blob.
Once a client finishes uploading the blob it'll receive a link from the server that can be used to retrieve the blob at a later time.

Note: The server side currently does not do any form of authentication and downloads blobs fully into memory first.
This obviously can be abused and crashed etc.
Do realize that at this time this software is considered experimental.

Why do we need this?

Hackers, social media, governments etc are increasingly infringing on our privacy and being able to safely and securely share information with others is vital in this day and age.
Closed source crypto solutions are bad since they can not be audited and verified by 3rd parties.
Commercial entities have proven to be unscrupulous and can not be trusted.

How does it work?

The tool leverages the ideas of the outstanding NaCl (http://nacl.cr.yp.to/) crypto suite.
It uses only free, not patented algorithms that were developed in academia that are seemingly untainted by government influence.
All messages are encrypted using NaCl boxes that use Curve25519, XSalsa20 and Poly1305 for encryption and public-key authenticators.
Additionally the mcrypt package (https://github.com/marcopeereboom/mcrypt) adds public-key signatures.

secfileshare builds on top of this and adds an ephemeral shared secret that encrypts the file that will be shared.
The ephemeral shared secret is then encrypted by the originator's private key and N recipients public keys.
The resulting blob does not contain any identifiable information regarding the originator or the recipients.

How do I start using it?

Install Go! See the following link for details http://golang.org/doc/install

Install secfileshare

	go get github.com/marcopeereboom/secfileshare.git

Run secfileshare without any parameters.
This will create your keys.

Note that secfileshare uses HTTPS URLs to distinguish if it is dealing with files or servers.

The process of sharing files is simple.
	1. Obtain the public key from the party you wish to share with.
	2. Upload file to server using the recipient public key.
	3. Share the link and your public-key with the recipient.

File to Server

Encrypt and upload a file to a single recipient
	secfileshare -in filename -out https://a.b.c:12345 RecipientPublicKey

Encrypt and upload a file to a multiple recipients
	secfileshare -in filename -out https://a.b.c:12345 Recipient1PublicKey Recipient2PublicKey Recipient3PublicKey

Encrypt and upload a file to a single recipient with an optional description
	secfileshare -d "you wanted this" -in filename -out https://a.b.c:12345 RecipientPublicKey

Note that if you want to be able to decrypt the blob yourself that you must provide your public-key as well.

Server to File

Download and decrypt a single file
	secfileshare https://a.b.c:12345/887123051

Download and decrypt multiple files
	secfileshare https://a.b.c:12345/887123051 https://a.b.c:12345/887123052 https://a.b.c:12345/887123053

Download and decrypt a single file to a specific filename
	secfileshare -out myfile https://a.b.c:12345/887123051

Do read the tool's help as well since it explains the -out parameter that is used to manipulate the out filenames.

File to File

If you want to share a blob without using a backend server you can use the file to file mode.

	secfileshare -in filename -out sharefilename -mode encrypt Recipient1PublicKey

Todo

This code is proof-of-concept and the following list is what needs to happen to mature

	* Switch to binary protocol
	* Chunk data instead so that we don't have to do everything everything in memory
	* Add authentication to both sides
	* Add MIME handlers in client so that it can auto launch viewers for downloaded files
	* Add a client GUI
	* Add server management using HTTPS
	* Figure out auto-PKI
*/
package main
<|endoftext|>


<commit_before>/*

*/
package filemeta

import (
	"io"
	"os"
	"crypto/md5"
	"crypto/sha1"
	"crypto/sha256"

	"github.com/hosom/gomagic"
)

// FileMeta holds basic information about a file that allows Mandrake
// to pass that metadata to plugins for usage within the plugin
type FileMeta struct {
	Filepath	string
	Md5			string
	Sha1		string
	Sha256		string
	Mime		string
}

// NewFileMeta creates and returns a FileMeta struct with all fields
// populated.
func NewFileMeta(fpath string) (fmeta FileMeta, err error) {
	fmeta = FileMeta{}
	fmeta.Filepath = fpath

	// Get the mime_type of the file utilizing libmagic
	m, err := magic.Open(magic.MAGIC_MIME_TYPE)
	if err != nil {
		return fmeta, err
	}

	fmeta.Mime, _ = m.File(fpath)

	// Get all hashes for the file
	fmeta.Md5, fmeta.Sha1, fmeta.Sha256, err = multihash(fpath)
	if err != nil {
		return fmeta, err
	}

	return fmeta, nil
}

// multihash hashes a file through multiple hashing algorithms in a single
// pass by taking advantage of Go's multiwriter implementation by copying the
// file to multiple io.Writer instances in one pass.
func multihash(fpath string) (string, string, string, error) {
	r, err := os.Open(fpath)
	if err != nil {
		return "", "", "", err
	}
	defer r.Close()

	md5_hasher := md5.New()
	sha1_hasher := sha1.New()
	sha256_hasher := sha256.New()

	w := io.MultiWriter(md5_hasher, sha1_hasher, sha256_hasher)
	if _, err = io.Copy(w, r); err != nil {
		return "", "", "", err
	}

	return string(md5_hasher.Sum(nil)), string(sha1_hasher.Sum(nil)), string(sha256_hasher.Sum(nil)), nil
}<commit_msg>update filemeta formatting<commit_after>/*

*/
package filemeta

import (
	"fmt"
	"io"
	"os"
	"crypto/md5"
	"crypto/sha1"
	"crypto/sha256"

	"github.com/hosom/gomagic"
)

// FileMeta holds basic information about a file that allows Mandrake
// to pass that metadata to plugins for usage within the plugin
type FileMeta struct {
	Filepath	string
	Md5			string
	Sha1		string
	Sha256		string
	Mime		string
}

// NewFileMeta creates and returns a FileMeta struct with all fields
// populated.
func NewFileMeta(fpath string) (fmeta FileMeta, err error) {
	fmeta = FileMeta{}
	fmeta.Filepath = fpath

	// Get the mime_type of the file utilizing libmagic
	m, err := magic.Open(magic.MAGIC_MIME_TYPE)
	if err != nil {
		return fmeta, err
	}

	fmeta.Mime, _ = m.File(fpath)

	// Get all hashes for the file
	fmeta.Md5, fmeta.Sha1, fmeta.Sha256, err = multihash(fpath)
	if err != nil {
		return fmeta, err
	}

	return fmeta, nil
}

// multihash hashes a file through multiple hashing algorithms in a single
// pass by taking advantage of Go's multiwriter implementation by copying the
// file to multiple io.Writer instances in one pass.
func multihash(fpath string) (string, string, string, error) {
	r, err := os.Open(fpath)
	if err != nil {
		return "", "", "", err
	}
	defer r.Close()

	md5_hasher := md5.New()
	sha1_hasher := sha1.New()
	sha256_hasher := sha256.New()

	w := io.MultiWriter(md5_hasher, sha1_hasher, sha256_hasher)
	if _, err = io.Copy(w, r); err != nil {
		return "", "", "", err
	}

	md5sum := fmt.Sprintf("%x", md5_hasher.Sum(nil))
	sha1sum := fmt.Sprintf("%x", sha1_hasher.Sum(nil))
	sha256sum := fmt.Sprintf("%x", sha256_hasher.Sum(nil))

	return md5sum, sha1sum, sha256sum, nil
}<|endoftext|>


<commit_before>/*

esc embeds files into go programs and provides http.FileSystem interfaces
to them.

It adds all named files or files recursively under named directories at the
path specified. The output file provides an http.FileSystem interface with
zero dependencies on packages outside the standard library.

Usage:
	esc [flag] [name ...]

The flags are:
	-o=""
		output filename, defaults to stdout
	-pkg="main"
		package name of output file, defaults to main
	-prefix=""
		strip given prefix from filenames
	-ignore=""
		regular expression for files to ignore
	-modtime=""
		Unix timestamp to override as modification time for all files

Accessing Embedded Files

After producing an output file, the assets may be accessed with the FS()
function, which takes a flag to use local assets instead (for local
development).

FS(Must)?(Byte|String) returns an asset as a (byte slice|string).
FSMust(Byte|String) panics if the asset is not found.

Example

Embedded assets can be served with HTTP using the http.FileServer.
Assuming you have a directory structure similar to the following:

	.
	├── main.go
	└── static
	    ├── css
	    │   └── style.css
	    └── index.html

Where main.go contains:

	package main

	import (
		"log"
		"net/http"
	)

	func main() {
		// FS() is created by esc and returns a http.Filesystem.
		http.Handle("/static/", http.FileServer(FS(false)))
		log.Fatal(http.ListenAndServe(":8080", nil))
	}

1. Generate the embedded data:
	esc -o static.go static
2. Start the server:
	go run main.go static.go
3. Access http://localhost:8080/static/index.html to view the files.

*/
package main
<commit_msg>Add example for go generate<commit_after>/*

esc embeds files into go programs and provides http.FileSystem interfaces
to them.

It adds all named files or files recursively under named directories at the
path specified. The output file provides an http.FileSystem interface with
zero dependencies on packages outside the standard library.

Usage:
	esc [flag] [name ...]

The flags are:
	-o=""
		output filename, defaults to stdout
	-pkg="main"
		package name of output file, defaults to main
	-prefix=""
		strip given prefix from filenames
	-ignore=""
		regular expression for files to ignore
	-modtime=""
		Unix timestamp to override as modification time for all files

Accessing Embedded Files

After producing an output file, the assets may be accessed with the FS()
function, which takes a flag to use local assets instead (for local
development).

FS(Must)?(Byte|String) returns an asset as a (byte slice|string).
FSMust(Byte|String) panics if the asset is not found.

Go Generate

esc can be invoked by go generate:

	//go:generate esc -o static.go -pkg server static

Example

Embedded assets can be served with HTTP using the http.FileServer.
Assuming you have a directory structure similar to the following:

	.
	├── main.go
	└── static
	    ├── css
	    │   └── style.css
	    └── index.html

Where main.go contains:

	package main

	import (
		"log"
		"net/http"
	)

	func main() {
		// FS() is created by esc and returns a http.Filesystem.
		http.Handle("/static/", http.FileServer(FS(false)))
		log.Fatal(http.ListenAndServe(":8080", nil))
	}

1. Generate the embedded data:
	esc -o static.go static
2. Start the server:
	go run main.go static.go
3. Access http://localhost:8080/static/index.html to view the files.

*/
package main
<|endoftext|>