<commit_before>// Copyright 2016 Mesosphere, 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 (
	"os"
	"reflect"
	"strings"
	"time"

	log "github.com/Sirupsen/logrus"

	frameworkCollector "github.com/dcos/dcos-metrics/collectors/framework"
	nodeCollector "github.com/dcos/dcos-metrics/collectors/node"
	"github.com/dcos/dcos-metrics/producers"
	httpProducer "github.com/dcos/dcos-metrics/producers/http"
	"github.com/dcos/dcos-metrics/util/http/profiler"
	//kafkaProducer "github.com/dcos/dcos-metrics/producers/kafka"
	//statsdProducer "github.com/dcos/dcos-metrics/producers/statsd"
)

func main() {
	// Get configuration
	cfg, err := getNewConfig(os.Args[1:])
	if err != nil {
		log.Fatal(err)
		os.Exit(1)
	}

	// Set logging level
	lvl, err := log.ParseLevel(cfg.LogLevel)
	if err != nil {
		log.Fatal(err)
		os.Exit(1)
	}
	log.SetLevel(lvl)

	// HTTP profiling
	if cfg.Collector.HTTPProfiler {
		log.Info("HTTP profiling enabled")
		go profiler.RunHTTPProfAccess()
	}

	var producerChans []chan<- producers.MetricsMessage

	// HTTP producer
	if producerIsConfigured("http", cfg) {
		log.Info("HTTP producer enabled")
		cfg.Producers.HTTPProducerConfig.DCOSRole = cfg.DCOSRole
		cfg.Producers.HTTPProducerConfig.CacheExpiry = time.Duration(cfg.Collector.MesosAgent.PollPeriod) * time.Minute * 2

		hp, httpProducerChan := httpProducer.New(
			cfg.Producers.HTTPProducerConfig)
		producerChans = append(producerChans, httpProducerChan)
		go hp.Run()
	}

	// Initialize and run the host-poller
	node, nodeChan := nodeCollector.New(*cfg.Collector.Node, cfg.nodeInfo)
	go node.RunPoller()

	// Initialize agent specific channels and run agent specific pollers
	// if role is of type agent
	frameworkCollectorChan := make(chan *frameworkCollector.AvroDatum)
	framework := frameworkCollector.New()
	cfg.Collector.MesosAgent.MetricsChan = make(chan producers.MetricsMessage)
	if cfg.DCOSRole == "agent" {
		go framework.RunFrameworkTCPListener(frameworkCollectorChan)
		go cfg.Collector.MesosAgent.RunPoller()
	}

	// Broadcast (many-to-many) messages from the collector to the various producers.
	for {
		select {

		case frameworkMessage := <-frameworkCollectorChan:
			pmm, err := frameworkMessage.Transform(cfg.MesosID, cfg.ClusterID, cfg.IPAddress)
			if err != nil {
				log.Error(err)
			}
			for _, producer := range producerChans {
				producer <- pmm
			}

		case nodeCollectorMetric := <-nodeChan:
			for _, producer := range producerChans {
				producer <- nodeCollectorMetric
			}

		case mesosAgentCollectorMetric := <-cfg.Collector.MesosAgent.MetricsChan:
			for _, producer := range producerChans {
				producer <- mesosAgentCollectorMetric
			}
		}
	}
}

// producerIsConfigured analyzes the ProducersConfig struct and determines if
// configuration exists for a given producer by name (i.e., is the "http"
// producer configured?). If a configuration exists, this function will return
// true, as a configured producer is an enabled one.
func producerIsConfigured(name string, cfg Config) bool {
	s := reflect.ValueOf(cfg.Producers)
	cfgType := s.Type()
	for i := 0; i < s.NumField(); i++ {
		if strings.Split(cfgType.Field(i).Tag.Get("yaml"), ",")[0] == name {
			return true
		}
	}
	return false
}
<commit_msg>(maint) remove dead imports<commit_after>// Copyright 2016 Mesosphere, 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 (
	"os"
	"reflect"
	"strings"
	"time"

	log "github.com/Sirupsen/logrus"

	frameworkCollector "github.com/dcos/dcos-metrics/collectors/framework"
	nodeCollector "github.com/dcos/dcos-metrics/collectors/node"
	"github.com/dcos/dcos-metrics/producers"
	httpProducer "github.com/dcos/dcos-metrics/producers/http"
	"github.com/dcos/dcos-metrics/util/http/profiler"
)

func main() {
	// Get configuration
	cfg, err := getNewConfig(os.Args[1:])
	if err != nil {
		log.Fatal(err)
		os.Exit(1)
	}

	// Set logging level
	lvl, err := log.ParseLevel(cfg.LogLevel)
	if err != nil {
		log.Fatal(err)
		os.Exit(1)
	}
	log.SetLevel(lvl)

	// HTTP profiling
	if cfg.Collector.HTTPProfiler {
		log.Info("HTTP profiling enabled")
		go profiler.RunHTTPProfAccess()
	}

	var producerChans []chan<- producers.MetricsMessage

	// HTTP producer
	if producerIsConfigured("http", cfg) {
		log.Info("HTTP producer enabled")
		cfg.Producers.HTTPProducerConfig.DCOSRole = cfg.DCOSRole
		cfg.Producers.HTTPProducerConfig.CacheExpiry = time.Duration(cfg.Collector.MesosAgent.PollPeriod) * time.Minute * 2

		hp, httpProducerChan := httpProducer.New(
			cfg.Producers.HTTPProducerConfig)
		producerChans = append(producerChans, httpProducerChan)
		go hp.Run()
	}

	// Initialize and run the host-poller
	node, nodeChan := nodeCollector.New(*cfg.Collector.Node, cfg.nodeInfo)
	go node.RunPoller()

	// Initialize agent specific channels and run agent specific pollers
	// if role is of type agent
	frameworkCollectorChan := make(chan *frameworkCollector.AvroDatum)
	framework := frameworkCollector.New()
	cfg.Collector.MesosAgent.MetricsChan = make(chan producers.MetricsMessage)
	if cfg.DCOSRole == "agent" {
		go framework.RunFrameworkTCPListener(frameworkCollectorChan)
		go cfg.Collector.MesosAgent.RunPoller()
	}

	// Broadcast (many-to-many) messages from the collector to the various producers.
	for {
		select {

		case frameworkMessage := <-frameworkCollectorChan:
			pmm, err := frameworkMessage.Transform(cfg.MesosID, cfg.ClusterID, cfg.IPAddress)
			if err != nil {
				log.Error(err)
			}
			for _, producer := range producerChans {
				producer <- pmm
			}

		case nodeCollectorMetric := <-nodeChan:
			for _, producer := range producerChans {
				producer <- nodeCollectorMetric
			}

		case mesosAgentCollectorMetric := <-cfg.Collector.MesosAgent.MetricsChan:
			for _, producer := range producerChans {
				producer <- mesosAgentCollectorMetric
			}
		}
	}
}

// producerIsConfigured analyzes the ProducersConfig struct and determines if
// configuration exists for a given producer by name (i.e., is the "http"
// producer configured?). If a configuration exists, this function will return
// true, as a configured producer is an enabled one.
func producerIsConfigured(name string, cfg Config) bool {
	s := reflect.ValueOf(cfg.Producers)
	cfgType := s.Type()
	for i := 0; i < s.NumField(); i++ {
		if strings.Split(cfgType.Field(i).Tag.Get("yaml"), ",")[0] == name {
			return true
		}
	}
	return false
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/base64"
	"fmt"
	"io/ioutil"
	"log"
	"strings"
)

func main() {
	raw, err := ioutil.ReadFile("activity.dat")

	if err != nil {
		log.Fatal(err)
	}

	encoded := strings.Split(string(raw), "\\n")
	var decoded []byte

	for _, line := range encoded {
		b, err := base64.StdEncoding.DecodeString(line)

		if err != nil {
			log.Fatal(err)
		}

		decoded = append(decoded, b...)
	}

	fmt.Println(decoded)
}
<commit_msg>Add GPS trace decoding code<commit_after>package main

import (
	"bytes"
	"encoding/base64"
	"encoding/binary"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"strings"
	"time"
)

type trackPoint struct {
	Longitude float32
	Latitude  float32
	Elevation float32
	Time      time.Time
}

func read(r io.Reader) (trackPoint, error) {
	var point trackPoint
	var timestamp int64

	if err := binary.Read(r, binary.BigEndian, &timestamp); err != nil {
		return trackPoint{}, nil
	}

	point.Time = time.Unix(timestamp/1000, timestamp%1000*1000)

	if err := binary.Read(r, binary.BigEndian, &point.Longitude); err != nil {
		return trackPoint{}, err
	}

	if err := binary.Read(r, binary.BigEndian, &point.Latitude); err != nil {
		return trackPoint{}, err
	}

	if err := binary.Read(r, binary.BigEndian, &point.Elevation); err != nil {
		return trackPoint{}, err
	}

	rest := make([]byte, 18)

	if err := binary.Read(r, binary.BigEndian, rest); err != nil {
		return trackPoint{}, err
	}

	return point, nil
}

func main() {
	raw, err := ioutil.ReadFile("activity.dat")

	if err != nil {
		log.Fatal(err)
	}

	encoded := strings.Split(string(raw), "\\n")
	var decoded []byte

	for _, line := range encoded {
		var b []byte
		b, err = base64.StdEncoding.DecodeString(line)

		if err != nil {
			log.Fatal(err)
		}

		decoded = append(decoded, b...)
	}

	buf := bytes.NewBuffer(decoded)
	var size int32

	if err = binary.Read(buf, binary.BigEndian, &size); err != nil {
		log.Fatal(err)
	}

	fmt.Println(size)

	for i := 0; i < int(size); i++ {
		point, err := read(buf)

		if err != nil {
			log.Fatal(err)
		}

		fmt.Printf("%+v\n", point)
	}
}
<|endoftext|>


<commit_before>package ditaconvert

import (
	"encoding/xml"
	"fmt"
	"io"
	"path"
	"strings"

	"github.com/raintreeinc/ditaconvert/html"
)

func TODO(context *Context, dec *xml.Decoder, start xml.StartElement) error {
	context.Encoder.WriteRaw(`<div class="conversion-error">TODO ` + start.Name.Local + `</div>`)
	dec.Skip()
	return nil
}

/* TODO: unify all rules
func Rename(tag string, attrs... xml.Attr) TokenProcessor {
	return func(context *Context, dec *xml.Decoder, start xml.StartElement) error {
		start.Name.Local = tag
		return context.EmitWithChildren(dec, start)
	}
}

func RenameWithClass(tag string, class string) TokenProcessor {
	return func(context *Context, dec *xml.Decoder, start xml.StartElement) error {
		start.Name.Local = tag
		setAttr(&start, "class", class)
		return context.EmitWithChildren(dec, start)
	}
}*/

func NewDefaultRules() *Rules {
	return &Rules{
		Rename: map[string]Renaming{
			// conversion
			"xref": {"a", ""},
			"link": {"a", ""},

			//lists
			"choices":         {"ul", ""},
			"choice":          {"li", ""},
			"steps-unordered": {"ul", ""},
			"steps":           {"ol", ""},
			"step":            {"li", ""}, // handled with a custom rule
			"substeps":        {"ol", ""},
			"substep":         {"li", ""}, // handled with a custom rule

			"b":     {"strong", ""},
			"i":     {"em", ""},
			"lines": {"pre", ""},

			"codeblock": {"pre", "codeblock"},
			"pre":       {"pre", "pre"},

			"codeph":      {"samp", "codeph"},
			"cmdname":     {"span", "cmdname"},
			"cmd":         {"span", "cmd"},
			"shortcut":    {"span", "shortcut"},
			"wintitle":    {"span", "wintitle"},
			"filepath":    {"span", "filepath"},
			"menucascade": {"span", "menucascade"},

			"option":   {"span", "option"},
			"synph":    {"span", ""},
			"delim":    {"span", ""},
			"sep":      {"span", ""},
			"parmname": {"span", ""},

			"userinput": {"kbd", "userinput"},

			"image": {"img", ""},

			// ui
			"uicontrol": {"b", ""},

			// divs
			"context":    {"div", ""},
			"result":     {"div", ""},
			"stepresult": {"div", ""},
			"stepxmp":    {"div", ""},
			"info":       {"div", ""},
			"note":       {"div", ""},
			"refsyn":     {"div", ""},
			"bodydiv":    {"div", ""},
			"fig":        {"div", ""},

			"prereq":  {"div", ""},
			"postreq": {"div", ""},

			"colspec": {"colgroup", ""},

			"row":   {"tr", ""},
			"entry": {"td", ""},

			// RAINTREE SPECIFIC
			"keystroke": {"b", "key"},
			"secright":  {"span", "secright"},

			// faq
			"faq":          {"dl", ""},
			"faq-item":     {"div", ""},
			"faq-question": {"dt", "dlterm"},
			"faq-answer":   {"dd", ""},

			//UI items
			"ui-item-list":        {"dl", ""},
			"ui-item":             {"div", ""},
			"ui-item-name":        {"dt", "dlterm"},
			"ui-item-description": {"dd", ""},

			// setup options
			"setup-options":            {"dl", ""},
			"setup-option":             {"div", ""},
			"setup-option-name":        {"dt", "dlterm"},
			"setup-option-description": {"dd", ""},

			"settingdesc": {"div", ""},
			"settingname": {"h2", ""},

			"section":    {"div", "section"},
			"example":    {"div", ""},
			"sectiondiv": {"div", ""},
			"title":      {"h2", "sectiontitle"},

			// ??
			"dlentry": {"div", ""},
			"dt":      {"dt", "dlterm"},

			"settings": {"div", "settings"},
			"setting":  {"div", "setting"},
		},
		Skip: map[string]bool{
			"br":            true,
			"draft-comment": true,

			// RAINTREE SPECIFIC
			"settinghead": true,
		},
		Unwrap: map[string]bool{
			"tgroup": true,
		},
		Custom: map[string]TokenProcessor{
			"a": func(context *Context, dec *xml.Decoder, start xml.StartElement) error {
				var href, desc string
				var internal bool

				href = getAttr(&start, "href")
				if href != "" {
					href, _, desc, internal = context.ResolveLinkInfo(href)
					setAttr(&start, "href", href)
				}

				if desc != "" && getAttr(&start, "title") == "" {
					setAttr(&start, "title", desc)
				}

				setAttr(&start, "scope", "")
				if internal && href != "" {
					//setAttr(&start, "data-link", href)
				}

				if getAttr(&start, "format") != "" && href != "" {
					setAttr(&start, "format", "")
					ext := strings.ToLower(path.Ext(href))
					if ext == ".pdf" || ext == ".doc" || ext == ".xml" || ext == ".rtf" || ext == ".zip" || ext == ".exe" {
						setAttr(&start, "download", path.Base(href))
					} else {
						setAttr(&start, "target", "_blank")
					}
				}

				return context.EmitWithChildren(dec, start)
			},
			"img": func(context *Context, dec *xml.Decoder, start xml.StartElement) error {
				href := getAttr(&start, "href")
				//setAttr(&start, "src", context.InlinedImageURL(href))
				setAttr(&start, "src", href)
				setAttr(&start, "href", "")

				placement := getAttr(&start, "placement")
				setAttr(&start, "placement", "")
				if placement == "break" {
					context.Encoder.WriteStart("p",
						xml.Attr{Name: xml.Name{Local: "class"}, Value: "image"})
				}

				err := context.EmitWithChildren(dec, start)

				if placement == "break" {
					context.Encoder.WriteEnd("p")
				}

				return err
			},
			"data": func(context *Context, dec *xml.Decoder, start xml.StartElement) error {
				datatype := strings.ToLower(getAttr(&start, "datatype"))
				if datatype == "rttutorial" {
					dec.Skip()
					href := getAttr(&start, "href")
					tag := fmt.Sprintf(`<video controls src="%s">Browser does not support video playback.</video>`, html.NormalizeURL(href))
					context.Encoder.WriteRaw(tag)
					return nil
				}

				return context.EmitWithChildren(dec, start)
			},
			"imagemap": ConvertImageMap,

			// RAINTREE SPECIFIC
			"settingdefault": func(context *Context, dec *xml.Decoder, start xml.StartElement) error {
				val, _ := html.XMLText(dec)
				if val != "" {
					return context.Encoder.WriteRaw("
Default value: " + val + "
")
				}
				return nil
			},
			"settinglevels": func(context *Context, dec *xml.Decoder, start xml.StartElement) error {
				context.check(context.Encoder.WriteRaw("
Levels where it can be defined:
"))
				return context.EmitWithChildren(dec, start)
			},
			"settingsample": func(context *Context, dec *xml.Decoder, start xml.StartElement) error {
				context.check(context.Encoder.WriteRaw("
Example:
"))
				return context.EmitWithChildren(dec, start)
			},

			"note": func(context *Context, dec *xml.Decoder, start xml.StartElement) error {
				typ := getAttr(&start, "type")
				if typ == "" {
					typ = "note"
				}
				setAttr(&start, "type", "")
				setAttr(&start, "class", typ)

				context.check(context.Encoder.WriteStart("div", start.Attr...))
				context.check(context.Encoder.WriteRaw(`<span class="` + typ + `title">` + strings.Title(typ) + `:</span> `))
				err := context.Recurse(dec)
				context.check(context.Encoder.WriteEnd("div"))
				return err
			},
			"menucascade": func(context *Context, dec *xml.Decoder, start xml.StartElement) error {
				start.Name.Local = "span"

				setAttr(&start, "class", "menucascade")
				// encode starting tag and attributes
				if err := context.Encoder.Encode(start); err != nil {
					return err
				}

				first := true

				// recurse on child tokens
				for {
					token, err := dec.Token()
					if err != nil {
						if err == io.EOF {
							return nil
						}
						return err
					}

					if _, ended := token.(xml.EndElement); ended {
						break
					}
					if _, starting := token.(xml.StartElement); starting {
						if !first {
							context.Encoder.WriteRaw(">")
						}
						first = false
					}
					if err := context.Handle(dec, token); err != nil {
						return err
					}
				}

				// always encode ending tag
				context.check(context.Encoder.Encode(xml.EndElement{start.Name}))

				return nil
			},

			"simpletable": HandleSimpleTable,
			"table":       HandleTable,

			"step": func(context *Context, dec *xml.Decoder, start xml.StartElement) error {
				start.Name.Local = "li"

				context.check(context.Encoder.Encode(start))
				context.Encoder.WriteRaw("(Optional) ")
				err := context.Recurse(dec)
				context.check(context.Encoder.Encode(xml.EndElement{start.Name}))

				return err
			},
			"substep": func(context *Context, dec *xml.Decoder, start xml.StartElement) error {
				start.Name.Local = "li"

				context.check(context.Encoder.Encode(start))
				context.Encoder.WriteRaw("(Optional) ")
				err := context.Recurse(dec)
				context.check(context.Encoder.Encode(xml.EndElement{start.Name}))

				return err
			},
		},
	}
}
<commit_msg>Mark optional steps correctly.<commit_after>package ditaconvert

import (
	"encoding/xml"
	"fmt"
	"io"
	"path"
	"strings"

	"github.com/raintreeinc/ditaconvert/html"
)

func TODO(context *Context, dec *xml.Decoder, start xml.StartElement) error {
	context.Encoder.WriteRaw(`<div class="conversion-error">TODO ` + start.Name.Local + `</div>`)
	dec.Skip()
	return nil
}

/* TODO: unify all rules
func Rename(tag string, attrs... xml.Attr) TokenProcessor {
	return func(context *Context, dec *xml.Decoder, start xml.StartElement) error {
		start.Name.Local = tag
		return context.EmitWithChildren(dec, start)
	}
}

func RenameWithClass(tag string, class string) TokenProcessor {
	return func(context *Context, dec *xml.Decoder, start xml.StartElement) error {
		start.Name.Local = tag
		setAttr(&start, "class", class)
		return context.EmitWithChildren(dec, start)
	}
}*/

func NewDefaultRules() *Rules {
	return &Rules{
		Rename: map[string]Renaming{
			// conversion
			"xref": {"a", ""},
			"link": {"a", ""},

			//lists
			"choices":         {"ul", ""},
			"choice":          {"li", ""},
			"steps-unordered": {"ul", ""},
			"steps":           {"ol", ""},
			"step":            {"li", ""}, // handled with a custom rule
			"substeps":        {"ol", ""},
			"substep":         {"li", ""}, // handled with a custom rule

			"b":     {"strong", ""},
			"i":     {"em", ""},
			"lines": {"pre", ""},

			"codeblock": {"pre", "codeblock"},
			"pre":       {"pre", "pre"},

			"codeph":      {"samp", "codeph"},
			"cmdname":     {"span", "cmdname"},
			"cmd":         {"span", "cmd"},
			"shortcut":    {"span", "shortcut"},
			"wintitle":    {"span", "wintitle"},
			"filepath":    {"span", "filepath"},
			"menucascade": {"span", "menucascade"},

			"option":   {"span", "option"},
			"synph":    {"span", ""},
			"delim":    {"span", ""},
			"sep":      {"span", ""},
			"parmname": {"span", ""},

			"userinput": {"kbd", "userinput"},

			"image": {"img", ""},

			// ui
			"uicontrol": {"b", ""},

			// divs
			"context":    {"div", ""},
			"result":     {"div", ""},
			"stepresult": {"div", ""},
			"stepxmp":    {"div", ""},
			"info":       {"div", ""},
			"note":       {"div", ""},
			"refsyn":     {"div", ""},
			"bodydiv":    {"div", ""},
			"fig":        {"div", ""},

			"prereq":  {"div", ""},
			"postreq": {"div", ""},

			"colspec": {"colgroup", ""},

			"row":   {"tr", ""},
			"entry": {"td", ""},

			// RAINTREE SPECIFIC
			"keystroke": {"b", "key"},
			"secright":  {"span", "secright"},

			// faq
			"faq":          {"dl", ""},
			"faq-item":     {"div", ""},
			"faq-question": {"dt", "dlterm"},
			"faq-answer":   {"dd", ""},

			//UI items
			"ui-item-list":        {"dl", ""},
			"ui-item":             {"div", ""},
			"ui-item-name":        {"dt", "dlterm"},
			"ui-item-description": {"dd", ""},

			// setup options
			"setup-options":            {"dl", ""},
			"setup-option":             {"div", ""},
			"setup-option-name":        {"dt", "dlterm"},
			"setup-option-description": {"dd", ""},

			"settingdesc": {"div", ""},
			"settingname": {"h2", ""},

			"section":    {"div", "section"},
			"example":    {"div", ""},
			"sectiondiv": {"div", ""},
			"title":      {"h2", "sectiontitle"},

			// ??
			"dlentry": {"div", ""},
			"dt":      {"dt", "dlterm"},

			"settings": {"div", "settings"},
			"setting":  {"div", "setting"},
		},
		Skip: map[string]bool{
			"br":            true,
			"draft-comment": true,

			// RAINTREE SPECIFIC
			"settinghead": true,
		},
		Unwrap: map[string]bool{
			"tgroup": true,
		},
		Custom: map[string]TokenProcessor{
			"a": func(context *Context, dec *xml.Decoder, start xml.StartElement) error {
				var href, desc string
				var internal bool

				href = getAttr(&start, "href")
				if href != "" {
					href, _, desc, internal = context.ResolveLinkInfo(href)
					setAttr(&start, "href", href)
				}

				if desc != "" && getAttr(&start, "title") == "" {
					setAttr(&start, "title", desc)
				}

				setAttr(&start, "scope", "")
				if internal && href != "" {
					//setAttr(&start, "data-link", href)
				}

				if getAttr(&start, "format") != "" && href != "" {
					setAttr(&start, "format", "")
					ext := strings.ToLower(path.Ext(href))
					if ext == ".pdf" || ext == ".doc" || ext == ".xml" || ext == ".rtf" || ext == ".zip" || ext == ".exe" {
						setAttr(&start, "download", path.Base(href))
					} else {
						setAttr(&start, "target", "_blank")
					}
				}

				return context.EmitWithChildren(dec, start)
			},
			"img": func(context *Context, dec *xml.Decoder, start xml.StartElement) error {
				href := getAttr(&start, "href")
				//setAttr(&start, "src", context.InlinedImageURL(href))
				setAttr(&start, "src", href)
				setAttr(&start, "href", "")

				placement := getAttr(&start, "placement")
				setAttr(&start, "placement", "")
				if placement == "break" {
					context.Encoder.WriteStart("p",
						xml.Attr{Name: xml.Name{Local: "class"}, Value: "image"})
				}

				err := context.EmitWithChildren(dec, start)

				if placement == "break" {
					context.Encoder.WriteEnd("p")
				}

				return err
			},
			"data": func(context *Context, dec *xml.Decoder, start xml.StartElement) error {
				datatype := strings.ToLower(getAttr(&start, "datatype"))
				if datatype == "rttutorial" {
					dec.Skip()
					href := getAttr(&start, "href")
					tag := fmt.Sprintf(`<video controls src="%s">Browser does not support video playback.</video>`, html.NormalizeURL(href))
					context.Encoder.WriteRaw(tag)
					return nil
				}

				return context.EmitWithChildren(dec, start)
			},
			"imagemap": ConvertImageMap,

			// RAINTREE SPECIFIC
			"settingdefault": func(context *Context, dec *xml.Decoder, start xml.StartElement) error {
				val, _ := html.XMLText(dec)
				if val != "" {
					return context.Encoder.WriteRaw("
Default value: " + val + "
")
				}
				return nil
			},
			"settinglevels": func(context *Context, dec *xml.Decoder, start xml.StartElement) error {
				context.check(context.Encoder.WriteRaw("
Levels where it can be defined:
"))
				return context.EmitWithChildren(dec, start)
			},
			"settingsample": func(context *Context, dec *xml.Decoder, start xml.StartElement) error {
				context.check(context.Encoder.WriteRaw("
Example:
"))
				return context.EmitWithChildren(dec, start)
			},

			"note": func(context *Context, dec *xml.Decoder, start xml.StartElement) error {
				typ := getAttr(&start, "type")
				if typ == "" {
					typ = "note"
				}
				setAttr(&start, "type", "")
				setAttr(&start, "class", typ)

				context.check(context.Encoder.WriteStart("div", start.Attr...))
				context.check(context.Encoder.WriteRaw(`<span class="` + typ + `title">` + strings.Title(typ) + `:</span> `))
				err := context.Recurse(dec)
				context.check(context.Encoder.WriteEnd("div"))
				return err
			},
			"menucascade": func(context *Context, dec *xml.Decoder, start xml.StartElement) error {
				start.Name.Local = "span"

				setAttr(&start, "class", "menucascade")
				// encode starting tag and attributes
				if err := context.Encoder.Encode(start); err != nil {
					return err
				}

				first := true

				// recurse on child tokens
				for {
					token, err := dec.Token()
					if err != nil {
						if err == io.EOF {
							return nil
						}
						return err
					}

					if _, ended := token.(xml.EndElement); ended {
						break
					}
					if _, starting := token.(xml.StartElement); starting {
						if !first {
							context.Encoder.WriteRaw(">")
						}
						first = false
					}
					if err := context.Handle(dec, token); err != nil {
						return err
					}
				}

				// always encode ending tag
				context.check(context.Encoder.Encode(xml.EndElement{start.Name}))

				return nil
			},

			"simpletable": HandleSimpleTable,
			"table":       HandleTable,

			"step": func(context *Context, dec *xml.Decoder, start xml.StartElement) error {
				start.Name.Local = "li"

				context.check(context.Encoder.Encode(start))
				if getAttr(&start, "importance") == "optional" {
					context.Encoder.WriteRaw("(Optional) ")
				}
				err := context.Recurse(dec)
				context.check(context.Encoder.Encode(xml.EndElement{start.Name}))

				return err
			},
			"substep": func(context *Context, dec *xml.Decoder, start xml.StartElement) error {
				start.Name.Local = "li"

				context.check(context.Encoder.Encode(start))
				if getAttr(&start, "importance") == "optional" {
					context.Encoder.WriteRaw("(Optional) ")
				}
				err := context.Recurse(dec)
				context.check(context.Encoder.Encode(xml.EndElement{start.Name}))

				return err
			},
		},
	}
}
<|endoftext|>


<commit_before>/*
Package vanity implements custom import paths (Go vanity URLs) as an HTTP
handler that can be installed at the vanity URL.
*/
package vanity

import (
	"fmt"
	"html/template"
	"net/http"
	"strings"
)

type config struct {
	importTag []string
	sourceTag *string
	redir     Redirector
}

// Configures the Handler. The only required option is WithImport.
type Option func(*config)

// Instructs the go tool where to fetch the repo at vcsRoot and the importPath
// that tree should be rooted at.
func WithImport(importPath, vcs, vcsRoot string) Option {
	importTag := "<meta name=\"go-import\" content=\"" + importPath + " " +
		vcs + " " + vcsRoot + "\">"
	return func(cfg *config) {
		cfg.importTag = append(cfg.importTag, importTag)
	}
}

// Instructs gddo (godoc.org) how to direct browsers to browsable source code
// for packages and their contents rooted at prefix.
//
// home specifies the home page of prefix, directory gives a format for how to
// browse a directory, and file gives a format for how to view a file and go to
// specific lines within it.
//
// More information can be found at https://github.com/golang/gddo/wiki/Source-Code-Links.
//
func WithSource(prefix, home, directory, file string) Option {
	sourceTag := "<meta name=\"go-source\" content=\"" + prefix + " " +
		home + " " + directory + " " + file + "\">"
	return func(cfg *config) {
		if cfg.sourceTag != nil {
			panic(fmt.Sprintf("vanity: existing source tag: %s", *cfg.sourceTag))
		}
		cfg.sourceTag = &sourceTag
	}
}

// When a browser navigates to the vanity URL of pkg, this function rewrites
// pkg to a browsable URL.
type Redirector func(pkg string) (url string)

// WithRedirector loads a redirector instance into the config.
func WithRedirector(redir Redirector) Option {
	return func(cfg *config) {
		if cfg.redir != nil {
			panic("vanity: existing Redirector")
		}
		cfg.redir = redir
	}
}

// MakeHandler creates a handler with custom options.
func MakeHandler(opts ...Option) http.Handler {
	return handlerFrom(compile(opts))
}

func compile(opts []Option) (*template.Template, Redirector) {
	// Process options.
	var cfg config
	for _, opt := range opts {
		opt(&cfg)
	}

	// A WithImport is required.
	if cfg.importTag == nil {
		panic("vanity: WithImport is required")
	}

	tags := make([]string, len(cfg.importTag))
	copy(tags, cfg.importTag)
	if cfg.sourceTag != nil {
		tags = append(tags, *cfg.sourceTag)
	}
	tagBlk := strings.Join(tags, "\n")

	h := fmt.Sprintf(`<!DOCTYPE html>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
%s
<meta http-equiv="refresh" content="0; url={{ . }}">

Please see here for documentation on this package.

`, tagBlk)

	// Use default GDDO Redirector.
	if cfg.redir == nil {
		cfg.redir = func(pkg string) string {
			return "https://godoc.org/" + pkg
		}
	}

	return template.Must(template.New("").Parse(h)), cfg.redir
}

func handlerFrom(tpl *template.Template, redir Redirector) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// Only method supported is GET.
		if r.Method != http.MethodGet {
			status := http.StatusMethodNotAllowed
			http.Error(w, http.StatusText(status), status)
			return
		}

		pkg := r.Host + r.URL.Path
		redirURL := redir(pkg)

		// Issue an HTTP redirect if this is definitely a browser.
		if r.FormValue("go-get") != "1" {
			http.Redirect(w, r, redirURL, http.StatusTemporaryRedirect)
			return
		}

		w.Header().Set("Cache-Control", "public, max-age=300")
		if err := tpl.ExecuteTemplate(w, "", redirURL); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
		}
	})
}

// Handler returns an http.Handler that serves the vanity URL information for a single
// repository. Each Option gives additional information to agents about the
// repository or provides help to browsers that may have navigated to the vanity
// URL. The WithImport Option is mandatory since the go tool requires it to
// fetch the repository.
func Handler(opts ...Option) http.Handler {
	return handlerFrom(compile(opts))
}

// Helpers for common VCSs.

// Redirects gddo to browsable source files for GitHub hosted repositories.
func WithGitHubStyleSource(importPath, repoPath, ref string) Option {
	directory := repoPath + "/tree/" + ref + "{/dir}"
	file := repoPath + "/blob/" + ref + "{/dir}/{file}#L{line}"

	return WithSource(importPath, repoPath, directory, file)
}

// Redirects gddo to browsable source files for Gogs hosted repositories.
func WithGogsStyleSource(importPath, repoPath, ref string) Option {
	directory := repoPath + "/src/" + ref + "{/dir}"
	file := repoPath + "/src/" + ref + "{/dir}/{file}#L{line}"

	return WithSource(importPath, repoPath, directory, file)
}

// Creates a Handler that serves a GitHub repository at a specific importPath.
func GitHubHandler(importPath, user, repo, gitScheme string) http.Handler {
	ghImportPath := "github.com/" + user + "/" + repo
	return Handler(
		WithImport(importPath, "git", gitScheme+"://"+ghImportPath),
		WithGitHubStyleSource(importPath, "https://"+ghImportPath, "master"),
	)
}

// Creates a Handler that serves a repository hosted with Gogs at host at a
// specific importPath.
func GogsHandler(importPath, host, user, repo, gitScheme string) http.Handler {
	gogsImportPath := host + "/" + user + "/" + repo
	return Handler(
		WithImport(importPath, "git", gitScheme+"://"+gogsImportPath),
		WithGogsStyleSource(importPath, "https://"+gogsImportPath, "master"),
	)
}
<commit_msg>vanity: support go modules<commit_after>/*
Package vanity implements custom import paths (Go vanity URLs) as an HTTP
handler that can be installed at the vanity URL.
*/
package vanity

import (
	"fmt"
	"html/template"
	"net/http"
	"strings"
)

type config struct {
	importTag []string
	sourceTag *string
	redir     Redirector
}

// Configures the Handler. The only required option is WithImport.
type Option func(*config)

// Instructs the go tool where to fetch the repo at vcsRoot and the importPath
// that tree should be rooted at.
func WithImport(importPath, vcs, vcsRoot string) Option {
	importTag := "<meta name=\"go-import\" content=\"" + importPath + " " +
		vcs + " " + vcsRoot + "\">"
	return func(cfg *config) {
		cfg.importTag = append(cfg.importTag, importTag)
	}
}

// WithGoModProxy adds a go module proxy to the option chain.
func WithGoModProxy(importPath, proxyServer string) Option {
	return WithImport(importPath, "mod", proxyServer)
}

// Instructs gddo (godoc.org) how to direct browsers to browsable source code
// for packages and their contents rooted at prefix.
//
// home specifies the home page of prefix, directory gives a format for how to
// browse a directory, and file gives a format for how to view a file and go to
// specific lines within it.
//
// More information can be found at https://github.com/golang/gddo/wiki/Source-Code-Links.
//
func WithSource(prefix, home, directory, file string) Option {
	sourceTag := "<meta name=\"go-source\" content=\"" + prefix + " " +
		home + " " + directory + " " + file + "\">"
	return func(cfg *config) {
		if cfg.sourceTag != nil {
			panic(fmt.Sprintf("vanity: existing source tag: %s", *cfg.sourceTag))
		}
		cfg.sourceTag = &sourceTag
	}
}

// When a browser navigates to the vanity URL of pkg, this function rewrites
// pkg to a browsable URL.
type Redirector func(pkg string) (url string)

// WithRedirector loads a redirector instance into the config.
func WithRedirector(redir Redirector) Option {
	return func(cfg *config) {
		if cfg.redir != nil {
			panic("vanity: existing Redirector")
		}
		cfg.redir = redir
	}
}

// MakeHandler creates a handler with custom options.
func MakeHandler(opts ...Option) http.Handler {
	return handlerFrom(compile(opts))
}

func compile(opts []Option) (*template.Template, Redirector) {
	// Process options.
	var cfg config
	for _, opt := range opts {
		opt(&cfg)
	}

	// A WithImport is required.
	if cfg.importTag == nil {
		panic("vanity: WithImport is required")
	}

	tags := make([]string, len(cfg.importTag))
	copy(tags, cfg.importTag)
	if cfg.sourceTag != nil {
		tags = append(tags, *cfg.sourceTag)
	}
	tagBlk := strings.Join(tags, "\n")

	h := fmt.Sprintf(`<!DOCTYPE html>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
%s
<meta http-equiv="refresh" content="0; url={{ . }}">

Please see here for documentation on this package.

`, tagBlk)

	// Use default GDDO Redirector.
	if cfg.redir == nil {
		cfg.redir = func(pkg string) string {
			return "https://godoc.org/" + pkg
		}
	}

	return template.Must(template.New("").Parse(h)), cfg.redir
}

func handlerFrom(tpl *template.Template, redir Redirector) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// Only method supported is GET.
		if r.Method != http.MethodGet {
			status := http.StatusMethodNotAllowed
			http.Error(w, http.StatusText(status), status)
			return
		}

		pkg := r.Host + r.URL.Path
		redirURL := redir(pkg)

		// Issue an HTTP redirect if this is definitely a browser.
		if r.FormValue("go-get") != "1" {
			http.Redirect(w, r, redirURL, http.StatusTemporaryRedirect)
			return
		}

		w.Header().Set("Cache-Control", "public, max-age=300")
		if err := tpl.ExecuteTemplate(w, "", redirURL); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
		}
	})
}

// Handler returns an http.Handler that serves the vanity URL information for a single
// repository. Each Option gives additional information to agents about the
// repository or provides help to browsers that may have navigated to the vanity
// URL. The WithImport Option is mandatory since the go tool requires it to
// fetch the repository.
func Handler(opts ...Option) http.Handler {
	return handlerFrom(compile(opts))
}

// Helpers for common VCSs.

// Redirects gddo to browsable source files for GitHub hosted repositories.
func WithGitHubStyleSource(importPath, repoPath, ref string) Option {
	directory := repoPath + "/tree/" + ref + "{/dir}"
	file := repoPath + "/blob/" + ref + "{/dir}/{file}#L{line}"

	return WithSource(importPath, repoPath, directory, file)
}

// Redirects gddo to browsable source files for Gogs hosted repositories.
func WithGogsStyleSource(importPath, repoPath, ref string) Option {
	directory := repoPath + "/src/" + ref + "{/dir}"
	file := repoPath + "/src/" + ref + "{/dir}/{file}#L{line}"

	return WithSource(importPath, repoPath, directory, file)
}

// Creates a Handler that serves a GitHub repository at a specific importPath.
func GitHubHandler(importPath, user, repo, gitScheme, proxyServer string) http.Handler {
	ghImportPath := "github.com/" + user + "/" + repo
	return Handler(
		WithImport(importPath, "git", gitScheme+"://"+ghImportPath),
		WithGoModProxy(importPath, proxyServer),
		WithGitHubStyleSource(importPath, "https://"+ghImportPath, "master"),
	)
}

// Creates a Handler that serves a repository hosted with Gogs at host at a
// specific importPath.
func GogsHandler(importPath, host, user, repo, gitScheme, proxyServer string) http.Handler {
	gogsImportPath := host + "/" + user + "/" + repo
	return Handler(
		WithImport(importPath, "git", gitScheme+"://"+gogsImportPath),
		WithGoModProxy(importPath, proxyServer),
		WithGogsStyleSource(importPath, "https://"+gogsImportPath, "master"),
	)
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"os"
	"os/user"
	"path"
	"strings"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/route53"
)

type recordSet struct {
	name         string
	value        string // ip
	rsType       string
	ttl          int64
	hostedZoneId string
}

const progName = "dyndns53"

func main() {
	log.SetPrefix(progName + ": ")
	log.SetFlags(0)

	var recSet recordSet
	var logFn string
	flag.StringVar(&recSet.name, "name", "", "record set name (domain)")
	flag.StringVar(&recSet.rsType, "type", "A", `record set type; "A" or "AAAA"`)
	flag.Int64Var(&recSet.ttl, "ttl", 300, "TTL (time to live) in seconds")
	flag.StringVar(&recSet.hostedZoneId, "zone", "", "hosted zone id")
	flag.StringVar(&logFn, "log", "", "file name to log to (default is stdout)")
	if len(os.Args) == 1 {
		flag.Usage()
		os.Exit(1)
	}
	flag.Parse()

	recSet.name = strings.TrimSuffix(recSet.name, ".") + "." // append . if missing
	if err := recSet.validate(); err != nil {
		log.Fatal(err)
	}

	if logFn != "" {
		f, err := os.OpenFile(logFn, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
		if err != nil {
			log.Fatalf("log file: %v", err)
		}
		defer f.Close()

		log.SetFlags(log.LstdFlags) // restore standard flags
		log.SetOutput(f)            // log to file
	}

	var err error
	recSet.value, err = getCurrentIP()
	if err != nil {
		log.Fatal(err)
	}

	domain := strings.TrimSuffix(recSet.name, ".")
	if domainResolvesToIP(domain, recSet.value) {
		log.Fatalf("%s already resolves to %s; nothing to do", domain, recSet.value)
	}

	resp, err := recSet.upsert()
	if err != nil {
		log.Fatal(err)
	}

	log.Println(resp)
}

func getCurrentIP() (string, error) {
	resp, err := http.Get("http://checkip.amazonaws.com/")
	if err != nil {
		return "", fmt.Errorf("getCurrentIP: %v", err)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("getCurrentIP: %v", err)
	}
	ip := strings.TrimSpace(string(body))
	return ip, nil
}

func domainResolvesToIP(domain, checkIP string) bool {
	ips, err := net.LookupIP(domain)
	if err != nil {
		return false
	}
	for _, ip := range ips {
		if ip.String() == checkIP {
			return true
		}
	}
	return false
}

func (rs *recordSet) upsert() (*route53.ChangeResourceRecordSetsOutput, error) {
	usr, err := user.Current()
	if err != nil {
		return nil, fmt.Errorf("(*recordSet).upsert: %v", err)
	}
	credentialsPath := path.Join(usr.HomeDir, ".aws", "credentials")
	credentials := credentials.NewSharedCredentials(credentialsPath, progName)

	sess, err := session.NewSession()
	if err != nil {
		return nil, fmt.Errorf("(*recordSet).upsert: %v", err)
	}

	svc := route53.New(sess, &aws.Config{Credentials: credentials})

	params := &route53.ChangeResourceRecordSetsInput{
		ChangeBatch: &route53.ChangeBatch{
			Changes: []*route53.Change{
				{
					Action: aws.String("UPSERT"),
					ResourceRecordSet: &route53.ResourceRecordSet{
						Name: aws.String(rs.name),
						Type: aws.String(rs.rsType),
						TTL:  aws.Int64(rs.ttl),
						ResourceRecords: []*route53.ResourceRecord{
							{
								Value: aws.String(rs.value),
							},
						},
					},
				},
			},
		},
		HostedZoneId: aws.String(rs.hostedZoneId),
	}
	resp, err := svc.ChangeResourceRecordSets(params)
	if err != nil {
		return nil, fmt.Errorf("(*recordSet).upsert: %v", err)
	}

	return resp, nil
}

func (rs *recordSet) validate() error {
	if rs.name == "" {
		return fmt.Errorf("missing record set name")
	}

	if !strings.HasSuffix(rs.name, ".") {
		return fmt.Errorf(`record set name must end with a "."`)
	}

	if rs.rsType == "" {
		return fmt.Errorf("missing record set type")
	}

	if rs.rsType != "A" && rs.rsType != "AAAA" {
		return fmt.Errorf("invalid record set type: %s", rs.rsType)
	}

	if rs.ttl < 1 {
		return fmt.Errorf("invalid record set TTL: %d", rs.ttl)
	}

	if rs.hostedZoneId == "" {
		return fmt.Errorf("missing hosted zone id")
	}

	return nil
}
<commit_msg>Remove some blank lines<commit_after>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"os"
	"os/user"
	"path"
	"strings"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/route53"
)

type recordSet struct {
	name         string
	value        string // ip
	rsType       string
	ttl          int64
	hostedZoneId string
}

const progName = "dyndns53"

func main() {
	log.SetPrefix(progName + ": ")
	log.SetFlags(0)

	var recSet recordSet
	var logFn string
	flag.StringVar(&recSet.name, "name", "", "record set name (domain)")
	flag.StringVar(&recSet.rsType, "type", "A", `record set type; "A" or "AAAA"`)
	flag.Int64Var(&recSet.ttl, "ttl", 300, "TTL (time to live) in seconds")
	flag.StringVar(&recSet.hostedZoneId, "zone", "", "hosted zone id")
	flag.StringVar(&logFn, "log", "", "file name to log to (default is stdout)")
	if len(os.Args) == 1 {
		flag.Usage()
		os.Exit(1)
	}
	flag.Parse()

	recSet.name = strings.TrimSuffix(recSet.name, ".") + "." // append . if missing
	if err := recSet.validate(); err != nil {
		log.Fatal(err)
	}

	if logFn != "" {
		f, err := os.OpenFile(logFn, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
		if err != nil {
			log.Fatalf("log file: %v", err)
		}
		defer f.Close()

		log.SetFlags(log.LstdFlags) // restore standard flags
		log.SetOutput(f)            // log to file
	}

	var err error
	recSet.value, err = getCurrentIP()
	if err != nil {
		log.Fatal(err)
	}

	domain := strings.TrimSuffix(recSet.name, ".")
	if domainResolvesToIP(domain, recSet.value) {
		log.Fatalf("%s already resolves to %s; nothing to do", domain, recSet.value)
	}

	resp, err := recSet.upsert()
	if err != nil {
		log.Fatal(err)
	}

	log.Println(resp)
}

func getCurrentIP() (string, error) {
	resp, err := http.Get("http://checkip.amazonaws.com/")
	if err != nil {
		return "", fmt.Errorf("getCurrentIP: %v", err)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("getCurrentIP: %v", err)
	}
	ip := strings.TrimSpace(string(body))
	return ip, nil
}

func domainResolvesToIP(domain, checkIP string) bool {
	ips, err := net.LookupIP(domain)
	if err != nil {
		return false
	}
	for _, ip := range ips {
		if ip.String() == checkIP {
			return true
		}
	}
	return false
}

func (rs *recordSet) upsert() (*route53.ChangeResourceRecordSetsOutput, error) {
	usr, err := user.Current()
	if err != nil {
		return nil, fmt.Errorf("(*recordSet).upsert: %v", err)
	}
	credentialsPath := path.Join(usr.HomeDir, ".aws", "credentials")
	credentials := credentials.NewSharedCredentials(credentialsPath, progName)

	sess, err := session.NewSession()
	if err != nil {
		return nil, fmt.Errorf("(*recordSet).upsert: %v", err)
	}

	svc := route53.New(sess, &aws.Config{Credentials: credentials})
	params := &route53.ChangeResourceRecordSetsInput{
		ChangeBatch: &route53.ChangeBatch{
			Changes: []*route53.Change{
				{
					Action: aws.String("UPSERT"),
					ResourceRecordSet: &route53.ResourceRecordSet{
						Name: aws.String(rs.name),
						Type: aws.String(rs.rsType),
						TTL:  aws.Int64(rs.ttl),
						ResourceRecords: []*route53.ResourceRecord{
							{
								Value: aws.String(rs.value),
							},
						},
					},
				},
			},
		},
		HostedZoneId: aws.String(rs.hostedZoneId),
	}
	resp, err := svc.ChangeResourceRecordSets(params)
	if err != nil {
		return nil, fmt.Errorf("(*recordSet).upsert: %v", err)
	}
	return resp, nil
}

func (rs *recordSet) validate() error {
	if rs.name == "" {
		return fmt.Errorf("missing record set name")
	}
	if !strings.HasSuffix(rs.name, ".") {
		return fmt.Errorf(`record set name must end with a "."`)
	}
	if rs.rsType == "" {
		return fmt.Errorf("missing record set type")
	}
	if rs.rsType != "A" && rs.rsType != "AAAA" {
		return fmt.Errorf("invalid record set type: %s", rs.rsType)
	}
	if rs.ttl < 1 {
		return fmt.Errorf("invalid record set TTL: %d", rs.ttl)
	}
	if rs.hostedZoneId == "" {
		return fmt.Errorf("missing hosted zone id")
	}
	return nil
}
<|endoftext|>


<commit_before>package ecs

import "github.com/jiangshengwu/aliyun-sdk-for-go/util"

type DiskService interface {
	CreateDisk(params map[string]interface{}) (CreateDiskResponse, error)
	DescribeDisks(params map[string]interface{}) (DescribeDisksResponse, error)
	AttachDisk(params map[string]interface{}) (AttachDiskResponse, error)
	DetachDisk(params map[string]interface{}) (DetachDiskResponse, error)
	ModifyDiskAttribute(params map[string]interface{}) (ModifyDiskAttributeResponse, error)
	DeleteDisk(params map[string]interface{}) (DeleteDiskResponse, error)
	ReInitDisk(params map[string]interface{}) (ReInitDiskResponse, error)
	ResetDisk(params map[string]interface{}) (ResetDiskResponse, error)
	ReplaceSystemDisk(params map[string]interface{}) (ReplaceSystemDiskResponse, error)
	ResizeDisk(params map[string]interface{}) (ResizeDiskResponse, error)
}

type DiskOperator struct {
	Common *util.CommonParam
}

// Response struct for CreateDisk
type CreateDiskResponse struct {
	util.ErrorResponse
	DiskId string `json:"DiskId"`
}

// Response struct for DescribeDisks
type DescribeDisksResponse struct {
	util.ErrorResponse
	AllDisks Disks `json:"Disks"`
}

type Disks struct {
	AllDisk []DiskItemType `json:"Disk"`
}

// See http://docs.aliyun.com/?spm=5176.775974174.2.4.BYfRJ2#/ecs/open-api/datatype&diskitemtype
type DiskItemType struct {
	DiskId             string         `json:"DiskId"`
	RegionId           string         `json:"RegionId"`
	ZoneId             string         `json:"ZoneId"`
	DiskName           string         `json:"DiskName"`
	Description        string         `json:"Description"`
	Type               string         `json:"Type"`
	Category           string         `json:"Category"`
	Size               int            `json:"Size"`
	ImageId            string         `json:"ImageId"`
	SourceSnapshotId   string         `json:"SourceSnapshotId"`
	ProductCode        string         `json:"ProductCode"`
	Portable           bool           `json:"Portable"`
	Status             string         `json:"Status"`
	AllOperationLocks  OperationLocks `json:"OperationLocks"`
	InstanceId         string         `json:"InstanceId"`
	Device             string         `json:"Device"`
	DeleteWithInstance bool           `json:"DeleteWithInstance"`
	DeleteAutoSnapshot bool           `json:"DeleteAutoSnapshot"`
	EnableAutoSnapshot bool           `json:"EnableAutoSnapshot"`
	CreationTime       string         `json:"CreationTime"`
	AttachedTime       string         `json:"AttachedTime"`
	DetachedTime       string         `json:"DetachedTime"`
}

// Response struct for AttachDisk
type AttachDiskResponse struct {
	util.ErrorResponse
}

// Response struct for DetachDisk
type DetachDiskResponse struct {
	util.ErrorResponse
}

// Response struct for ModifyDiskAttribute
type ModifyDiskAttributeResponse struct {
	util.ErrorResponse
}

// Response struct for DeleteDisk
type DeleteDiskResponse struct {
	util.ErrorResponse
}

// Response struct for ReInitDisk
type ReInitDiskResponse struct {
	util.ErrorResponse
}

// Response struct for ResetDisk
type ResetDiskResponse struct {
	util.ErrorResponse
}

// Response struct for ReplaceSystemDisk
type ReplaceSystemDiskResponse struct {
	util.ErrorResponse
	DiskId string `json:"DiskId"`
}

// Response struct for ResizeDisk
type ResizeDiskResponse struct {
	util.ErrorResponse
}

func (op *DiskOperator) CreateDisk(params map[string]interface{}) (CreateDiskResponse, error) {
	var resp CreateDiskResponse
	err := op.Common.Request(util.GetFuncName(1), params, &resp)
	return resp, err
}

func (op *DiskOperator) DescribeDisks(params map[string]interface{}) (DescribeDisksResponse, error) {
	var resp DescribeDisksResponse
	err := op.Common.Request(util.GetFuncName(1), params, &resp)
	return resp, err
}

func (op *DiskOperator) AttachDisk(params map[string]interface{}) (AttachDiskResponse, error) {
	var resp AttachDiskResponse
	err := op.Common.Request(util.GetFuncName(1), params, &resp)
	return resp, err
}

func (op *DiskOperator) DetachDisk(params map[string]interface{}) (DetachDiskResponse, error) {
	var resp DetachDiskResponse
	err := op.Common.Request(util.GetFuncName(1), params, &resp)
	return resp, err
}

func (op *DiskOperator) ModifyDiskAttribute(params map[string]interface{}) (ModifyDiskAttributeResponse, error) {
	var resp ModifyDiskAttributeResponse
	err := op.Common.Request(util.GetFuncName(1), params, &resp)
	return resp, err
}

func (op *DiskOperator) DeleteDisk(params map[string]interface{}) (DeleteDiskResponse, error) {
	var resp DeleteDiskResponse
	err := op.Common.Request(util.GetFuncName(1), params, &resp)
	return resp, err
}

func (op *DiskOperator) ReInitDisk(params map[string]interface{}) (ReInitDiskResponse, error) {
	var resp ReInitDiskResponse
	err := op.Common.Request(util.GetFuncName(1), params, &resp)
	return resp, err
}

func (op *DiskOperator) ResetDisk(params map[string]interface{}) (ResetDiskResponse, error) {
	var resp ResetDiskResponse
	err := op.Common.Request(util.GetFuncName(1), params, &resp)
	return resp, err
}

func (op *DiskOperator) ReplaceSystemDisk(params map[string]interface{}) (ReplaceSystemDiskResponse, error) {
	var resp ReplaceSystemDiskResponse
	err := op.Common.Request(util.GetFuncName(1), params, &resp)
	return resp, err
}

func (op *DiskOperator) ResizeDisk(params map[string]interface{}) (ResizeDiskResponse, error) {
	var resp ResizeDiskResponse
	err := op.Common.Request(util.GetFuncName(1), params, &resp)
	return resp, err
}
<commit_msg>fix disk response<commit_after>package ecs

import "github.com/jiangshengwu/aliyun-sdk-for-go/util"

type DiskService interface {
	CreateDisk(params map[string]interface{}) (CreateDiskResponse, error)
	DescribeDisks(params map[string]interface{}) (DescribeDisksResponse, error)
	AttachDisk(params map[string]interface{}) (AttachDiskResponse, error)
	DetachDisk(params map[string]interface{}) (DetachDiskResponse, error)
	ModifyDiskAttribute(params map[string]interface{}) (ModifyDiskAttributeResponse, error)
	DeleteDisk(params map[string]interface{}) (DeleteDiskResponse, error)
	ReInitDisk(params map[string]interface{}) (ReInitDiskResponse, error)
	ResetDisk(params map[string]interface{}) (ResetDiskResponse, error)
	ReplaceSystemDisk(params map[string]interface{}) (ReplaceSystemDiskResponse, error)
	ResizeDisk(params map[string]interface{}) (ResizeDiskResponse, error)
}

type DiskOperator struct {
	Common *util.CommonParam
}

// Response struct for CreateDisk
type CreateDiskResponse struct {
	util.ErrorResponse
	DiskId string `json:"DiskId"`
}

// Response struct for DescribeDisks
type DescribeDisksResponse struct {
	util.PageResponse
	util.ErrorResponse
	AllDisks Disks `json:"Disks"`
}

type Disks struct {
	AllDisk []DiskItemType `json:"Disk"`
}

// See http://docs.aliyun.com/?spm=5176.775974174.2.4.BYfRJ2#/ecs/open-api/datatype&diskitemtype
type DiskItemType struct {
	DiskId             string         `json:"DiskId"`
	RegionId           string         `json:"RegionId"`
	ZoneId             string         `json:"ZoneId"`
	DiskName           string         `json:"DiskName"`
	Description        string         `json:"Description"`
	Type               string         `json:"Type"`
	Category           string         `json:"Category"`
	Size               int            `json:"Size"`
	ImageId            string         `json:"ImageId"`
	SourceSnapshotId   string         `json:"SourceSnapshotId"`
	ProductCode        string         `json:"ProductCode"`
	Portable           bool           `json:"Portable"`
	Status             string         `json:"Status"`
	AllOperationLocks  OperationLocks `json:"OperationLocks"`
	InstanceId         string         `json:"InstanceId"`
	Device             string         `json:"Device"`
	DeleteWithInstance bool           `json:"DeleteWithInstance"`
	DeleteAutoSnapshot bool           `json:"DeleteAutoSnapshot"`
	EnableAutoSnapshot bool           `json:"EnableAutoSnapshot"`
	CreationTime       string         `json:"CreationTime"`
	AttachedTime       string         `json:"AttachedTime"`
	DetachedTime       string         `json:"DetachedTime"`
}

// Response struct for AttachDisk
type AttachDiskResponse struct {
	util.ErrorResponse
}

// Response struct for DetachDisk
type DetachDiskResponse struct {
	util.ErrorResponse
}

// Response struct for ModifyDiskAttribute
type ModifyDiskAttributeResponse struct {
	util.ErrorResponse
}

// Response struct for DeleteDisk
type DeleteDiskResponse struct {
	util.ErrorResponse
}

// Response struct for ReInitDisk
type ReInitDiskResponse struct {
	util.ErrorResponse
}

// Response struct for ResetDisk
type ResetDiskResponse struct {
	util.ErrorResponse
}

// Response struct for ReplaceSystemDisk
type ReplaceSystemDiskResponse struct {
	util.ErrorResponse
	DiskId string `json:"DiskId"`
}

// Response struct for ResizeDisk
type ResizeDiskResponse struct {
	util.ErrorResponse
}

func (op *DiskOperator) CreateDisk(params map[string]interface{}) (CreateDiskResponse, error) {
	var resp CreateDiskResponse
	err := op.Common.Request(util.GetFuncName(1), params, &resp)
	return resp, err
}

func (op *DiskOperator) DescribeDisks(params map[string]interface{}) (DescribeDisksResponse, error) {
	var resp DescribeDisksResponse
	err := op.Common.Request(util.GetFuncName(1), params, &resp)
	return resp, err
}

func (op *DiskOperator) AttachDisk(params map[string]interface{}) (AttachDiskResponse, error) {
	var resp AttachDiskResponse
	err := op.Common.Request(util.GetFuncName(1), params, &resp)
	return resp, err
}

func (op *DiskOperator) DetachDisk(params map[string]interface{}) (DetachDiskResponse, error) {
	var resp DetachDiskResponse
	err := op.Common.Request(util.GetFuncName(1), params, &resp)
	return resp, err
}

func (op *DiskOperator) ModifyDiskAttribute(params map[string]interface{}) (ModifyDiskAttributeResponse, error) {
	var resp ModifyDiskAttributeResponse
	err := op.Common.Request(util.GetFuncName(1), params, &resp)
	return resp, err
}

func (op *DiskOperator) DeleteDisk(params map[string]interface{}) (DeleteDiskResponse, error) {
	var resp DeleteDiskResponse
	err := op.Common.Request(util.GetFuncName(1), params, &resp)
	return resp, err
}

func (op *DiskOperator) ReInitDisk(params map[string]interface{}) (ReInitDiskResponse, error) {
	var resp ReInitDiskResponse
	err := op.Common.Request(util.GetFuncName(1), params, &resp)
	return resp, err
}

func (op *DiskOperator) ResetDisk(params map[string]interface{}) (ResetDiskResponse, error) {
	var resp ResetDiskResponse
	err := op.Common.Request(util.GetFuncName(1), params, &resp)
	return resp, err
}

func (op *DiskOperator) ReplaceSystemDisk(params map[string]interface{}) (ReplaceSystemDiskResponse, error) {
	var resp ReplaceSystemDiskResponse
	err := op.Common.Request(util.GetFuncName(1), params, &resp)
	return resp, err
}

func (op *DiskOperator) ResizeDisk(params map[string]interface{}) (ResizeDiskResponse, error) {
	var resp ResizeDiskResponse
	err := op.Common.Request(util.GetFuncName(1), params, &resp)
	return resp, err
}
<|endoftext|>


<commit_before>package main

import (
  "fmt"
)

// with the restriction that 2nw − r − 1 is a Mersenne prime
const (
  mersenne_twister_n = 624 // degree of recurrence
  mersenne_twister_m = 397 // middle word, or the number of parallel sequences, 1 ≤ m ≤ n
  mersenne_twister_r = 31 // separation point of one word, or the number of bits of the lower bitmask, 0 ≤ r ≤ w - 1
  mersenne_twister_a = 0x9908B0DF // coefficients of the rational normal form twist matrix
  mersenne_twister_b = 0x9D2C5680 // TGFSR(R) tempering bitmasks
  mersenne_twister_c = 0xEFC60000 // TGFSR(R) tempering bitmasks
  mersenne_twister_s = 7 // TGFSR(R) tempering bit shifts
  mersenne_twister_t = 15 // TGFSR(R) tempering bit shifts
  mersenne_twister_u = 11 // additional Mersenne Twister tempering bit shifts
  mersenne_twister_l = 18 // additional Mersenne Twister tempering bit shifts
)

type MersenneTwister struct {
  State [mersenne_twister_n]uint32
  index int
}

func NewMersenneTwister() MersenneTwister {
  m := MersenneTwister{}
  return m
}

func (m *MersenneTwister) Seed(seed uint32) {
  m.index = 0
  m.State[0] = seed
  for i := 1; i < mersenne_twister_n; i++ {
    t := m.State[i - 1] ^ (m.State[i - 1] >> 30)
    m.State[i] = 1812433253 * (t + uint32(i))
  }
}

func (m *MersenneTwister) generate_numbers() {
  for i := 0; i < mersenne_twister_n; i++ {
    y := (m.State[i] & 0x80000000) + (m.State[(i + 1) % mersenne_twister_n] & 0x7fffffff)
    m.State[i] = m.State[(i + mersenne_twister_m) % mersenne_twister_n] ^ (y >> 1)
    if y % 2 != 0 {
      m.State[i] = m.State[i] ^ mersenne_twister_a
    }
  }
}

func (m *MersenneTwister) Urand32() uint32 {
  if m.index == 0 {
    m.generate_numbers()
  }

  y := m.State[m.index]
  y = y ^ (y >> mersenne_twister_u)
  y = y ^ ((y << mersenne_twister_s) & mersenne_twister_b)
  y = y ^ ((y << mersenne_twister_t) & mersenne_twister_c)
  y = y ^ (y >> mersenne_twister_l)

  m.index = (m.index + 1) % mersenne_twister_n
  return y
}

func (m *MersenneTwister) coded_xor(urand32 uint32, changebit_index uint32, xorbit_index uint32) uint32 {
  changebit_shift_index := 31 - changebit_index
  xorbit_shift_index := 31 - xorbit_index

  changebit := (urand32 >> changebit_shift_index) & 1
  xorbit := (urand32 >> xorbit_shift_index) & 1
  result := changebit ^ xorbit

  if changebit == 1 && result == 0 {
    urand32 -= (1 << changebit_shift_index)
  } else if changebit == 0 && result == 1 {
    urand32 += (1 << changebit_shift_index)
  }

  return urand32
}

func (m *MersenneTwister) coded_and_xor(urand32 uint32, uand32 uint32, changebit_index uint32, xorbit_index uint32) uint32 {
  xorbit_shift_index := 31 - xorbit_index
  changebit_shift_index := 31 - changebit_index

  changebit := (urand32 >> changebit_shift_index) & 1
  uandbit := (uand32 >> changebit_shift_index) & 1
  xorbit := (urand32 >> xorbit_shift_index) & 1
  result := xorbit & uandbit

  result = changebit ^ result

  if changebit == 1 && result == 0 {
    urand32 -= (1 << changebit_shift_index)
  } else if changebit == 0 && result == 1 {
    urand32 += (1 << changebit_shift_index)
  }

  return urand32
}

func (m *MersenneTwister) Urand32ToState(urand32 uint32) uint32 {
  for i := uint32(18); i <= 31; i++ {
    urand32 = m.coded_xor(urand32, i, i - 18)
  }

  for i := uint32(16); true; i-- {
    urand32 = m.coded_and_xor(urand32, 4022730752, i, i + 15)
    if i == 0 { break }
  }

  for i := uint32(24); true; i-- {
    urand32 = m.coded_and_xor(urand32, 2636928640, i, i + 7)
    if i == 0 { break }
  }

  for i := uint32(11); i <= 31; i++ {
    urand32 = m.coded_xor(urand32, i, i - 11)
  }

  return urand32
}

func main() {
  m := NewMersenneTwister()
  m.Seed(0)

  for j := 0; j < 1000; j++ {
    for i := 0; i < 623; i++ {
      v := m.Urand32()

      li := m.index - 1
      if li < 0 { li = 0 }
      s0 := m.State[li]
      s1 := m.Urand32ToState(v)

      if s0 != s1 {
        fmt.Printf("%d %d, %d != %d\n", i, v, s0, s1)
      }
    }
    // evens out so we get generate_numbers called again
    m.Urand32()
  }
}
<commit_msg>Added SeedFromUrand32s ability to Mersenne Twister, to make simulating a generator from values tidier.<commit_after>package main

import (
  "fmt"
)

// with the restriction that 2nw − r − 1 is a Mersenne prime
const (
  mersenne_twister_n = 624 // degree of recurrence
  mersenne_twister_m = 397 // middle word, or the number of parallel sequences, 1 ≤ m ≤ n
  mersenne_twister_r = 31 // separation point of one word, or the number of bits of the lower bitmask, 0 ≤ r ≤ w - 1
  mersenne_twister_a = 0x9908B0DF // coefficients of the rational normal form twist matrix
  mersenne_twister_b = 0x9D2C5680 // TGFSR(R) tempering bitmasks
  mersenne_twister_c = 0xEFC60000 // TGFSR(R) tempering bitmasks
  mersenne_twister_s = 7 // TGFSR(R) tempering bit shifts
  mersenne_twister_t = 15 // TGFSR(R) tempering bit shifts
  mersenne_twister_u = 11 // additional Mersenne Twister tempering bit shifts
  mersenne_twister_l = 18 // additional Mersenne Twister tempering bit shifts
)

type MersenneTwister struct {
  State [mersenne_twister_n]uint32
  index int
}

func NewMersenneTwister() MersenneTwister {
  m := MersenneTwister{}
  return m
}

func (m *MersenneTwister) Seed(seed uint32) {
  m.index = 0
  m.State[0] = seed
  for i := 1; i < mersenne_twister_n; i++ {
    t := m.State[i - 1] ^ (m.State[i - 1] >> 30)
    m.State[i] = 1812433253 * (t + uint32(i))
  }
}

func (m *MersenneTwister) SeedFromUrand32s(urand32s [mersenne_twister_n]uint32) {
  m.index = 0
  for i := 0; i < len(urand32s); i++ {
    m.State[i] = m.Urand32ToState(urand32s[i])
  }
}

func (m *MersenneTwister) generate_numbers() {
  for i := 0; i < mersenne_twister_n; i++ {
    y := (m.State[i] & 0x80000000) + (m.State[(i + 1) % mersenne_twister_n] & 0x7fffffff)
    m.State[i] = m.State[(i + mersenne_twister_m) % mersenne_twister_n] ^ (y >> 1)
    if y % 2 != 0 {
      m.State[i] = m.State[i] ^ mersenne_twister_a
    }
  }
}

func (m *MersenneTwister) Urand32() uint32 {
  if m.index == 0 {
    m.generate_numbers()
  }

  y := m.State[m.index]
  y = y ^ (y >> mersenne_twister_u)
  y = y ^ ((y << mersenne_twister_s) & mersenne_twister_b)
  y = y ^ ((y << mersenne_twister_t) & mersenne_twister_c)
  y = y ^ (y >> mersenne_twister_l)

  m.index = (m.index + 1) % mersenne_twister_n
  return y
}

func (m *MersenneTwister) coded_xor(urand32 uint32, changebit_index uint32, xorbit_index uint32) uint32 {
  changebit_shift_index := 31 - changebit_index
  xorbit_shift_index := 31 - xorbit_index

  changebit := (urand32 >> changebit_shift_index) & 1
  xorbit := (urand32 >> xorbit_shift_index) & 1
  result := changebit ^ xorbit

  if changebit == 1 && result == 0 {
    urand32 -= (1 << changebit_shift_index)
  } else if changebit == 0 && result == 1 {
    urand32 += (1 << changebit_shift_index)
  }

  return urand32
}

func (m *MersenneTwister) coded_and_xor(urand32 uint32, uand32 uint32, changebit_index uint32, xorbit_index uint32) uint32 {
  xorbit_shift_index := 31 - xorbit_index
  changebit_shift_index := 31 - changebit_index

  changebit := (urand32 >> changebit_shift_index) & 1
  uandbit := (uand32 >> changebit_shift_index) & 1
  xorbit := (urand32 >> xorbit_shift_index) & 1
  result := xorbit & uandbit

  result = changebit ^ result

  if changebit == 1 && result == 0 {
    urand32 -= (1 << changebit_shift_index)
  } else if changebit == 0 && result == 1 {
    urand32 += (1 << changebit_shift_index)
  }

  return urand32
}

func (m *MersenneTwister) Urand32ToState(urand32 uint32) uint32 {
  for i := uint32(18); i <= 31; i++ {
    urand32 = m.coded_xor(urand32, i, i - 18)
  }

  for i := uint32(16); true; i-- {
    urand32 = m.coded_and_xor(urand32, mersenne_twister_c, i, i + 15)
    if i == 0 { break }
  }

  for i := uint32(24); true; i-- {
    urand32 = m.coded_and_xor(urand32, mersenne_twister_b, i, i + 7)
    if i == 0 { break }
  }

  for i := uint32(11); i <= 31; i++ {
    urand32 = m.coded_xor(urand32, i, i - 11)
  }

  return urand32
}

func main() {
  m := NewMersenneTwister()
  m.Seed(0)

  var urand32s [624]uint32
  for i := 0; i < len(urand32s); i++ {
    urand32s[i] = m.Urand32()
  }

  m2 := NewMersenneTwister()
  m2.SeedFromUrand32s(urand32s)

  for i := 0; i < 10000; i++ {
    fmt.Printf("%d = %d\n", m.Urand32(), m2.Urand32())
  }
}
<|endoftext|>


<commit_before>package library

import (
	"encoding/json"
	"github.com/nytlabs/streamtools/st/blocks" // blocks
	"github.com/nytlabs/streamtools/st/util"
	"encoding/xml"
	"fmt"
	"github.com/mikedewar/aws4"
	"io/ioutil"
	"net/url"
	"strings"
	"log"
	"time"
	"net"
	"net/http"
    "sync"
)

type sqsMessage struct {
	Body          []string `xml:"ReceiveMessageResult>Message>Body"`
	ReceiptHandle []string `xml:"ReceiveMessageResult>Message>ReceiptHandle"`
}

func dialTimeout(network, addr string) (net.Conn, error) {
    return net.DialTimeout(network, addr, time.Duration(2 * time.Second))
}

func (b *FromSQS) listener() {
	b.lock.Lock()
	lAuth := map[string]string{}
	for k, _ := range b.auth {
		lAuth[k] = b.auth[k]
	}
	b.listening = true
	b.lock.Unlock()

	transport := http.Transport{
        Dial: dialTimeout,
    }

	httpclient := &http.Client{
        Transport: &transport,
    }

	keys := &aws4.Keys{
		AccessKey: lAuth["AccessKey"],
		SecretKey: lAuth["AccessSecret"],
	}

	sqsclient := &aws4.Client{Keys: keys, Client: httpclient}

	query := url.Values{}
	query.Set("Action", "ReceiveMessage")
	query.Set("AttributeName", "All")
	query.Set("Version", lAuth["APIVersion"])
	query.Set("SignatureVersion", lAuth["SignatureVersion"])
	query.Set("WaitTimeSeconds", lAuth["WaitTimeSeconds"])
	query.Set("MaxNumberOfMessages", lAuth["MaxNumberOfMessages"])
	queryurl := lAuth["SQSEndpoint"] + query.Encode()

    for {
    	select {
    	case <-b.stop:
    		log.Println("Exiting SQS read loop")
    		return
    	default:
			var m sqsMessage
			var m1 map[string]interface{}

			resp, err := sqsclient.Get(queryurl)

			if err != nil {
				continue
			}

			body, err := ioutil.ReadAll(resp.Body)
			if err != nil {
				continue
			}

			resp.Body.Close()

			err = xml.Unmarshal(body, &m)
			if err != nil {
				continue
			}

			if len(m.Body) == 0 {
				continue
			}

			for _, body := range m.Body {
				err = json.Unmarshal([]byte(body), &m1)
				if err != nil {
					continue
				}
				msgString, ok := m1["Message"].(string)
				if !ok {
					continue
				}
				msgs := strings.Split(msgString, "\n")
				for _, msg := range msgs {
					if len(msg) == 0 {
						continue
					}

					go func(outmsg string){
						stop := time.NewTimer(1 * time.Second)
						select {
							case b.fromListener <- []byte(outmsg):
							case <-stop.C:
								return
						}
					}(msg)

				}
			}

			delquery := url.Values{}
			delquery.Set("Action", "DeleteMessageBatch")
			delquery.Set("Version", lAuth["APIVersion"])
			delquery.Set("SignatureVersion", lAuth["SignatureVersion"])
			for i, r := range m.ReceiptHandle {
				id := fmt.Sprintf("DeleteMessageBatchRequestEntry.%d.Id", (i + 1))
				receipt := fmt.Sprintf("DeleteMessageBatchRequestEntry.%d.ReceiptHandle", (i + 1))
				delquery.Add(id, fmt.Sprintf("msg%d", (i+1)))
				delquery.Add(receipt, r)
			}
			delurl := lAuth["SQSEndpoint"] + delquery.Encode()

			resp, err = sqsclient.Get(delurl)
			if err != nil {
				continue
			}

			resp.Body.Close()
    	}
    }
}

// specify those channels we're going to use to communicate with streamtools
type FromSQS struct {
	blocks.Block
	queryrule    chan chan interface{}
	inrule       chan interface{}
	out          chan interface{}
	quit         chan interface{}

    lock         sync.Mutex
    listening    bool
    fromListener chan []byte
    auth         map[string]string
    stop 		 chan bool
}

// we need to build a simple factory so that streamtools can make new blocks of this kind
func NewFromSQS() blocks.BlockInterface {
	return &FromSQS{}
}

// Setup is called once before running the block. We build up the channels and specify what kind of block this is.
func (b *FromSQS) Setup() {
	b.Kind = "fromSQS"
	b.inrule = b.InRoute("rule")
	b.queryrule = b.QueryRoute("rule")
	b.quit = b.Quit()
	b.out = b.Broadcast()
	b.fromListener = make(chan []byte)
	b.stop = make(chan bool)
	b.auth = map[string]string{
		"SQSEndpoint":  "",
		"AccessKey":    "",
		"AccessSecret": "",
		"APIVersion":      "2012-11-05",
		"SignatureVersion": "4",
		"WaitTimeSeconds": "0",
		"MaxNumberOfMessages": "10",
	}
}

func (b *FromSQS) stopListening() {
	if b.listening {
		b.stop <- true
		b.listening = false
	}
}

// Run is the block's main loop. Here we listen on the different channels we set up.
func (b *FromSQS) Run() {
	var err error

	for {
		select {
		case msgI := <-b.inrule:
			for k, _ := range b.auth {
				b.auth[k], err = util.ParseString(msgI, k)
				if err != nil {
					b.Error(err)
					break
				}
			}

			b.stopListening()
			go b.listener()
		case <-b.quit:
			b.stopListening()
			return
		case msg := <-b.fromListener:
			var outMsg interface{}
			err := json.Unmarshal(msg, &outMsg)
			if err != nil {
				b.Error(err)
				continue
			}
			b.out <- outMsg
		case respChan := <-b.queryrule:
			// deal with a query request
			respChan <- b.auth
		}
	}
}
<commit_msg>Rules are map[string]interface{}s as annoying as that is...<commit_after>package library

import (
	"encoding/json"
	"encoding/xml"
	"fmt"
	"github.com/mikedewar/aws4"
	"github.com/nytlabs/streamtools/st/blocks" // blocks
	"github.com/nytlabs/streamtools/st/util"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"net/url"
	"strings"
	"sync"
	"time"
)

type sqsMessage struct {
	Body          []string `xml:"ReceiveMessageResult>Message>Body"`
	ReceiptHandle []string `xml:"ReceiveMessageResult>Message>ReceiptHandle"`
}

func dialTimeout(network, addr string) (net.Conn, error) {
	return net.DialTimeout(network, addr, time.Duration(2*time.Second))
}

func (b *FromSQS) listener() {
	b.lock.Lock()
	lAuth := map[string]string{}
	var err error
	for k, _ := range b.auth {
		lAuth[k], err = util.ParseString(b.auth, k)
		if err != nil {
			b.Error(err)
			break
		}
	}
	b.listening = true
	b.lock.Unlock()

	transport := http.Transport{
		Dial: dialTimeout,
	}

	httpclient := &http.Client{
		Transport: &transport,
	}

	keys := &aws4.Keys{
		AccessKey: lAuth["AccessKey"],
		SecretKey: lAuth["AccessSecret"],
	}

	sqsclient := &aws4.Client{Keys: keys, Client: httpclient}

	query := url.Values{}
	query.Set("Action", "ReceiveMessage")
	query.Set("AttributeName", "All")
	query.Set("Version", lAuth["APIVersion"])
	query.Set("SignatureVersion", lAuth["SignatureVersion"])
	query.Set("WaitTimeSeconds", lAuth["WaitTimeSeconds"])
	query.Set("MaxNumberOfMessages", lAuth["MaxNumberOfMessages"])
	queryurl := lAuth["SQSEndpoint"] + query.Encode()

	for {
		select {
		case <-b.stop:
			log.Println("Exiting SQS read loop")
			return
		default:
			var m sqsMessage
			var m1 map[string]interface{}

			resp, err := sqsclient.Get(queryurl)

			if err != nil {
				continue
			}

			body, err := ioutil.ReadAll(resp.Body)
			if err != nil {
				continue
			}

			resp.Body.Close()

			err = xml.Unmarshal(body, &m)
			if err != nil {
				continue
			}

			if len(m.Body) == 0 {
				continue
			}

			for _, body := range m.Body {
				err = json.Unmarshal([]byte(body), &m1)
				if err != nil {
					continue
				}
				msgString, ok := m1["Message"].(string)
				if !ok {
					continue
				}
				msgs := strings.Split(msgString, "\n")
				for _, msg := range msgs {
					if len(msg) == 0 {
						continue
					}

					go func(outmsg string) {
						stop := time.NewTimer(1 * time.Second)
						select {
						case b.fromListener <- []byte(outmsg):
						case <-stop.C:
							return
						}
					}(msg)

				}
			}

			delquery := url.Values{}
			delquery.Set("Action", "DeleteMessageBatch")
			delquery.Set("Version", lAuth["APIVersion"])
			delquery.Set("SignatureVersion", lAuth["SignatureVersion"])
			for i, r := range m.ReceiptHandle {
				id := fmt.Sprintf("DeleteMessageBatchRequestEntry.%d.Id", (i + 1))
				receipt := fmt.Sprintf("DeleteMessageBatchRequestEntry.%d.ReceiptHandle", (i + 1))
				delquery.Add(id, fmt.Sprintf("msg%d", (i+1)))
				delquery.Add(receipt, r)
			}
			delurl := lAuth["SQSEndpoint"] + delquery.Encode()

			resp, err = sqsclient.Get(delurl)
			if err != nil {
				continue
			}

			resp.Body.Close()
		}
	}
}

// specify those channels we're going to use to communicate with streamtools
type FromSQS struct {
	blocks.Block
	queryrule chan chan interface{}
	inrule    chan interface{}
	out       chan interface{}
	quit      chan interface{}

	lock         sync.Mutex
	listening    bool
	fromListener chan []byte
	auth         map[string]interface{}
	stop         chan bool
}

// we need to build a simple factory so that streamtools can make new blocks of this kind
func NewFromSQS() blocks.BlockInterface {
	return &FromSQS{}
}

// Setup is called once before running the block. We build up the channels and specify what kind of block this is.
func (b *FromSQS) Setup() {
	b.Kind = "fromSQS"
	b.inrule = b.InRoute("rule")
	b.queryrule = b.QueryRoute("rule")
	b.quit = b.Quit()
	b.out = b.Broadcast()
	b.fromListener = make(chan []byte)
	b.stop = make(chan bool)
	b.auth = map[string]interface{}{
		"SQSEndpoint":         "",
		"AccessKey":           "",
		"AccessSecret":        "",
		"APIVersion":          "2012-11-05",
		"SignatureVersion":    "4",
		"WaitTimeSeconds":     "0",
		"MaxNumberOfMessages": "10",
	}
}

func (b *FromSQS) stopListening() {
	if b.listening {
		b.stop <- true
		b.listening = false
	}
}

// Run is the block's main loop. Here we listen on the different channels we set up.
func (b *FromSQS) Run() {
	var err error

	for {
		select {
		case msgI := <-b.inrule:
			for k, _ := range b.auth {
				b.auth[k], err = util.ParseString(msgI, k)
				if err != nil {
					b.Error(err)
					break
				}
			}

			b.stopListening()
			go b.listener()
		case <-b.quit:
			b.stopListening()
			return
		case msg := <-b.fromListener:
			var outMsg interface{}
			err := json.Unmarshal(msg, &outMsg)
			if err != nil {
				b.Error(err)
				continue
			}
			b.out <- outMsg
		case respChan := <-b.queryrule:
			// deal with a query request
			respChan <- b.auth
		}
	}
}
<|endoftext|>


<commit_before>// Automatically generated by MockGen. DO NOT EDIT!
// Source: tracker.go

package state

import (
	gomock "code.google.com/p/gomock/gomock"
)

// Mock of Tracker interface
type MockTracker struct {
	ctrl     *gomock.Controller
	recorder *_MockTrackerRecorder
}

// Recorder for MockTracker (not exported)
type _MockTrackerRecorder struct {
	mock *MockTracker
}

func NewMockTracker(ctrl *gomock.Controller) *MockTracker {
	mock := &MockTracker{ctrl: ctrl}
	mock.recorder = &_MockTrackerRecorder{mock}
	return mock
}

func (_m *MockTracker) EXPECT() *_MockTrackerRecorder {
	return _m.recorder
}

func (_m *MockTracker) NewNick(nick string) *Nick {
	ret := _m.ctrl.Call(_m, "NewNick", nick)
	ret0, _ := ret[0].(*Nick)
	return ret0
}

func (_mr *_MockTrackerRecorder) NewNick(arg0 interface{}) *gomock.Call {
	return _mr.mock.ctrl.RecordCall(_mr.mock, "NewNick", arg0)
}

func (_m *MockTracker) GetNick(nick string) *Nick {
	ret := _m.ctrl.Call(_m, "GetNick", nick)
	ret0, _ := ret[0].(*Nick)
	return ret0
}

func (_mr *_MockTrackerRecorder) GetNick(arg0 interface{}) *gomock.Call {
	return _mr.mock.ctrl.RecordCall(_mr.mock, "GetNick", arg0)
}

func (_m *MockTracker) ReNick(old string, neu string) *Nick {
	ret := _m.ctrl.Call(_m, "ReNick", old, neu)
	ret0, _ := ret[0].(*Nick)
	return ret0
}

func (_mr *_MockTrackerRecorder) ReNick(arg0, arg1 interface{}) *gomock.Call {
	return _mr.mock.ctrl.RecordCall(_mr.mock, "ReNick", arg0, arg1)
}

func (_m *MockTracker) DelNick(nick string) *Nick {
	ret := _m.ctrl.Call(_m, "DelNick", nick)
	ret0, _ := ret[0].(*Nick)
	return ret0
}

func (_mr *_MockTrackerRecorder) DelNick(arg0 interface{}) *gomock.Call {
	return _mr.mock.ctrl.RecordCall(_mr.mock, "DelNick", arg0)
}

func (_m *MockTracker) NickInfo(nick string, ident string, host string, name string) *Nick {
	ret := _m.ctrl.Call(_m, "NickInfo", nick, ident, host, name)
	ret0, _ := ret[0].(*Nick)
	return ret0
}

func (_mr *_MockTrackerRecorder) NickInfo(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
	return _mr.mock.ctrl.RecordCall(_mr.mock, "NickInfo", arg0, arg1, arg2, arg3)
}

func (_m *MockTracker) NickModes(nick string, modestr string) *Nick {
	ret := _m.ctrl.Call(_m, "NickModes", nick, modestr)
	ret0, _ := ret[0].(*Nick)
	return ret0
}

func (_mr *_MockTrackerRecorder) NickModes(arg0, arg1 interface{}) *gomock.Call {
	return _mr.mock.ctrl.RecordCall(_mr.mock, "NickModes", arg0, arg1)
}

func (_m *MockTracker) NewChannel(channel string) *Channel {
	ret := _m.ctrl.Call(_m, "NewChannel", channel)
	ret0, _ := ret[0].(*Channel)
	return ret0
}

func (_mr *_MockTrackerRecorder) NewChannel(arg0 interface{}) *gomock.Call {
	return _mr.mock.ctrl.RecordCall(_mr.mock, "NewChannel", arg0)
}

func (_m *MockTracker) GetChannel(channel string) *Channel {
	ret := _m.ctrl.Call(_m, "GetChannel", channel)
	ret0, _ := ret[0].(*Channel)
	return ret0
}

func (_mr *_MockTrackerRecorder) GetChannel(arg0 interface{}) *gomock.Call {
	return _mr.mock.ctrl.RecordCall(_mr.mock, "GetChannel", arg0)
}

func (_m *MockTracker) DelChannel(channel string) *Channel {
	ret := _m.ctrl.Call(_m, "DelChannel", channel)
	ret0, _ := ret[0].(*Channel)
	return ret0
}

func (_mr *_MockTrackerRecorder) DelChannel(arg0 interface{}) *gomock.Call {
	return _mr.mock.ctrl.RecordCall(_mr.mock, "DelChannel", arg0)
}

func (_m *MockTracker) Topic(channel string, topic string) *Channel {
	ret := _m.ctrl.Call(_m, "Topic", channel, topic)
	ret0, _ := ret[0].(*Channel)
	return ret0
}

func (_mr *_MockTrackerRecorder) Topic(arg0, arg1 interface{}) *gomock.Call {
	return _mr.mock.ctrl.RecordCall(_mr.mock, "Topic", arg0, arg1)
}

func (_m *MockTracker) ChannelModes(channel string, modestr string, modeargs ...string) *Channel {
	_s := []interface{}{channel, modestr}
	for _, _x := range modeargs {
		_s = append(_s, _x)
	}
	ret := _m.ctrl.Call(_m, "ChannelModes", _s...)
	ret0, _ := ret[0].(*Channel)
	return ret0
}

func (_mr *_MockTrackerRecorder) ChannelModes(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
	_s := append([]interface{}{arg0, arg1}, arg2...)
	return _mr.mock.ctrl.RecordCall(_mr.mock, "ChannelModes", _s...)
}

func (_m *MockTracker) Me() *Nick {
	ret := _m.ctrl.Call(_m, "Me")
	ret0, _ := ret[0].(*Nick)
	return ret0
}

func (_mr *_MockTrackerRecorder) Me() *gomock.Call {
	return _mr.mock.ctrl.RecordCall(_mr.mock, "Me")
}

func (_m *MockTracker) IsOn(channel string, nick string) (*ChanPrivs, bool) {
	ret := _m.ctrl.Call(_m, "IsOn", channel, nick)
	ret0, _ := ret[0].(*ChanPrivs)
	ret1, _ := ret[1].(bool)
	return ret0, ret1
}

func (_mr *_MockTrackerRecorder) IsOn(arg0, arg1 interface{}) *gomock.Call {
	return _mr.mock.ctrl.RecordCall(_mr.mock, "IsOn", arg0, arg1)
}

func (_m *MockTracker) Associate(channel string, nick string) *ChanPrivs {
	ret := _m.ctrl.Call(_m, "Associate", channel, nick)
	ret0, _ := ret[0].(*ChanPrivs)
	return ret0
}

func (_mr *_MockTrackerRecorder) Associate(arg0, arg1 interface{}) *gomock.Call {
	return _mr.mock.ctrl.RecordCall(_mr.mock, "Associate", arg0, arg1)
}

func (_m *MockTracker) Dissociate(channel string, nick string) {
	_m.ctrl.Call(_m, "Dissociate", channel, nick)
}

func (_mr *_MockTrackerRecorder) Dissociate(arg0, arg1 interface{}) *gomock.Call {
	return _mr.mock.ctrl.RecordCall(_mr.mock, "Dissociate", arg0, arg1)
}

func (_m *MockTracker) Wipe() {
	_m.ctrl.Call(_m, "Wipe")
}

func (_mr *_MockTrackerRecorder) Wipe() *gomock.Call {
	return _mr.mock.ctrl.RecordCall(_mr.mock, "Wipe")
}

func (_m *MockTracker) String() string {
	ret := _m.ctrl.Call(_m, "String")
	ret0, _ := ret[0].(string)
	return ret0
}

func (_mr *_MockTrackerRecorder) String() *gomock.Call {
	return _mr.mock.ctrl.RecordCall(_mr.mock, "String")
}
<commit_msg>fix gmock url<commit_after>// Automatically generated by MockGen. DO NOT EDIT!
// Source: tracker.go

package state

import (
	gomock "github.com/golang/mock/gomock"
)

// Mock of Tracker interface
type MockTracker struct {
	ctrl     *gomock.Controller
	recorder *_MockTrackerRecorder
}

// Recorder for MockTracker (not exported)
type _MockTrackerRecorder struct {
	mock *MockTracker
}

func NewMockTracker(ctrl *gomock.Controller) *MockTracker {
	mock := &MockTracker{ctrl: ctrl}
	mock.recorder = &_MockTrackerRecorder{mock}
	return mock
}

func (_m *MockTracker) EXPECT() *_MockTrackerRecorder {
	return _m.recorder
}

func (_m *MockTracker) NewNick(nick string) *Nick {
	ret := _m.ctrl.Call(_m, "NewNick", nick)
	ret0, _ := ret[0].(*Nick)
	return ret0
}

func (_mr *_MockTrackerRecorder) NewNick(arg0 interface{}) *gomock.Call {
	return _mr.mock.ctrl.RecordCall(_mr.mock, "NewNick", arg0)
}

func (_m *MockTracker) GetNick(nick string) *Nick {
	ret := _m.ctrl.Call(_m, "GetNick", nick)
	ret0, _ := ret[0].(*Nick)
	return ret0
}

func (_mr *_MockTrackerRecorder) GetNick(arg0 interface{}) *gomock.Call {
	return _mr.mock.ctrl.RecordCall(_mr.mock, "GetNick", arg0)
}

func (_m *MockTracker) ReNick(old string, neu string) *Nick {
	ret := _m.ctrl.Call(_m, "ReNick", old, neu)
	ret0, _ := ret[0].(*Nick)
	return ret0
}

func (_mr *_MockTrackerRecorder) ReNick(arg0, arg1 interface{}) *gomock.Call {
	return _mr.mock.ctrl.RecordCall(_mr.mock, "ReNick", arg0, arg1)
}

func (_m *MockTracker) DelNick(nick string) *Nick {
	ret := _m.ctrl.Call(_m, "DelNick", nick)
	ret0, _ := ret[0].(*Nick)
	return ret0
}

func (_mr *_MockTrackerRecorder) DelNick(arg0 interface{}) *gomock.Call {
	return _mr.mock.ctrl.RecordCall(_mr.mock, "DelNick", arg0)
}

func (_m *MockTracker) NickInfo(nick string, ident string, host string, name string) *Nick {
	ret := _m.ctrl.Call(_m, "NickInfo", nick, ident, host, name)
	ret0, _ := ret[0].(*Nick)
	return ret0
}

func (_mr *_MockTrackerRecorder) NickInfo(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
	return _mr.mock.ctrl.RecordCall(_mr.mock, "NickInfo", arg0, arg1, arg2, arg3)
}

func (_m *MockTracker) NickModes(nick string, modestr string) *Nick {
	ret := _m.ctrl.Call(_m, "NickModes", nick, modestr)
	ret0, _ := ret[0].(*Nick)
	return ret0
}

func (_mr *_MockTrackerRecorder) NickModes(arg0, arg1 interface{}) *gomock.Call {
	return _mr.mock.ctrl.RecordCall(_mr.mock, "NickModes", arg0, arg1)
}

func (_m *MockTracker) NewChannel(channel string) *Channel {
	ret := _m.ctrl.Call(_m, "NewChannel", channel)
	ret0, _ := ret[0].(*Channel)
	return ret0
}

func (_mr *_MockTrackerRecorder) NewChannel(arg0 interface{}) *gomock.Call {
	return _mr.mock.ctrl.RecordCall(_mr.mock, "NewChannel", arg0)
}

func (_m *MockTracker) GetChannel(channel string) *Channel {
	ret := _m.ctrl.Call(_m, "GetChannel", channel)
	ret0, _ := ret[0].(*Channel)
	return ret0
}

func (_mr *_MockTrackerRecorder) GetChannel(arg0 interface{}) *gomock.Call {
	return _mr.mock.ctrl.RecordCall(_mr.mock, "GetChannel", arg0)
}

func (_m *MockTracker) DelChannel(channel string) *Channel {
	ret := _m.ctrl.Call(_m, "DelChannel", channel)
	ret0, _ := ret[0].(*Channel)
	return ret0
}

func (_mr *_MockTrackerRecorder) DelChannel(arg0 interface{}) *gomock.Call {
	return _mr.mock.ctrl.RecordCall(_mr.mock, "DelChannel", arg0)
}

func (_m *MockTracker) Topic(channel string, topic string) *Channel {
	ret := _m.ctrl.Call(_m, "Topic", channel, topic)
	ret0, _ := ret[0].(*Channel)
	return ret0
}

func (_mr *_MockTrackerRecorder) Topic(arg0, arg1 interface{}) *gomock.Call {
	return _mr.mock.ctrl.RecordCall(_mr.mock, "Topic", arg0, arg1)
}

func (_m *MockTracker) ChannelModes(channel string, modestr string, modeargs ...string) *Channel {
	_s := []interface{}{channel, modestr}
	for _, _x := range modeargs {
		_s = append(_s, _x)
	}
	ret := _m.ctrl.Call(_m, "ChannelModes", _s...)
	ret0, _ := ret[0].(*Channel)
	return ret0
}

func (_mr *_MockTrackerRecorder) ChannelModes(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
	_s := append([]interface{}{arg0, arg1}, arg2...)
	return _mr.mock.ctrl.RecordCall(_mr.mock, "ChannelModes", _s...)
}

func (_m *MockTracker) Me() *Nick {
	ret := _m.ctrl.Call(_m, "Me")
	ret0, _ := ret[0].(*Nick)
	return ret0
}

func (_mr *_MockTrackerRecorder) Me() *gomock.Call {
	return _mr.mock.ctrl.RecordCall(_mr.mock, "Me")
}

func (_m *MockTracker) IsOn(channel string, nick string) (*ChanPrivs, bool) {
	ret := _m.ctrl.Call(_m, "IsOn", channel, nick)
	ret0, _ := ret[0].(*ChanPrivs)
	ret1, _ := ret[1].(bool)
	return ret0, ret1
}

func (_mr *_MockTrackerRecorder) IsOn(arg0, arg1 interface{}) *gomock.Call {
	return _mr.mock.ctrl.RecordCall(_mr.mock, "IsOn", arg0, arg1)
}

func (_m *MockTracker) Associate(channel string, nick string) *ChanPrivs {
	ret := _m.ctrl.Call(_m, "Associate", channel, nick)
	ret0, _ := ret[0].(*ChanPrivs)
	return ret0
}

func (_mr *_MockTrackerRecorder) Associate(arg0, arg1 interface{}) *gomock.Call {
	return _mr.mock.ctrl.RecordCall(_mr.mock, "Associate", arg0, arg1)
}

func (_m *MockTracker) Dissociate(channel string, nick string) {
	_m.ctrl.Call(_m, "Dissociate", channel, nick)
}

func (_mr *_MockTrackerRecorder) Dissociate(arg0, arg1 interface{}) *gomock.Call {
	return _mr.mock.ctrl.RecordCall(_mr.mock, "Dissociate", arg0, arg1)
}

func (_m *MockTracker) Wipe() {
	_m.ctrl.Call(_m, "Wipe")
}

func (_mr *_MockTrackerRecorder) Wipe() *gomock.Call {
	return _mr.mock.ctrl.RecordCall(_mr.mock, "Wipe")
}

func (_m *MockTracker) String() string {
	ret := _m.ctrl.Call(_m, "String")
	ret0, _ := ret[0].(string)
	return ret0
}

func (_mr *_MockTrackerRecorder) String() *gomock.Call {
	return _mr.mock.ctrl.RecordCall(_mr.mock, "String")
}
<|endoftext|>


<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 util contains utility functions related to systemd that applications
// can use to check things like whether systemd is running.
package util

import (
	"os"
)

// IsRunningSystemd checks whether the host was booted with systemd as its init
// system. This functions similar to systemd's `sd_booted(3)`: internally, it
// checks whether /run/systemd/system/ exists and is a directory.
// http://www.freedesktop.org/software/systemd/man/sd_booted.html
func IsRunningSystemd() bool {
	fi, err := os.Lstat("/run/systemd/system")
	if err != nil {
		return false
	}
	return fi.IsDir()
}
<commit_msg>util: add GetRunningSlice+RunningFromSystemService<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 util contains utility functions related to systemd that applications
// can use to check things like whether systemd is running.  Note that some of
// these functions attempt to manually load systemd libraries at runtime rather
// than linking against them.
package util

// #cgo LDFLAGS: -ldl
// #include <stdlib.h>
// #include <dlfcn.h>
// #include <sys/types.h>
//
// int
// my_sd_pid_get_owner_uid(void *f, pid_t pid, uid_t *uid)
// {
//   int (*sd_pid_get_owner_uid)(pid_t, uid_t *);
//
//   sd_pid_get_owner_uid = (int (*)(pid_t, uid_t *))f;
//   return sd_pid_get_owner_uid(pid, uid);
// }
//
// int
// my_sd_pid_get_slice(void *f, pid_t pid, char **slice)
// {
//   int (*sd_pid_get_slice)(pid_t, char **);
//
//   sd_pid_get_slice = (int (*)(pid_t, char **))f;
//   return sd_pid_get_slice(pid, slice);
// }
//
import "C"
import (
	"fmt"
	"os"
	"syscall"
	"unsafe"
)

// getHandle tries to get a handle to a systemd library (.so), attempting to
// access it by several different names and returning the first that is
// successfully opened. Callers are responsible for closing the handler.
// Returns nil if no library can be found.
func getHandle() (unsafe.Pointer, string) {
	for _, name := range []string{
		// systemd < 209
		"libsystemd-login.so",
		"libsystemd-login.so.0",

		// systemd >= 209 merged libsystemd-login into libsystemd proper
		"libsystemd.so",
		"libsystemd.so.0",
	} {
		libname := C.CString(name)
		defer C.free(unsafe.Pointer(libname))
		handle := C.dlopen(libname, C.RTLD_LAZY)
		if handle != nil {
			return handle, name
		}
	}
	return nil, ""
}

// GetRunningSlice attempts to retrieve the name of the systemd slice in which
// the current process is running.
func GetRunningSlice() (slice string, err error) {
	handle, libname := getHandle()
	if handle == nil {
		err = fmt.Errorf("error opening libsystemd-login.so")
		return
	}
	defer func() {
		if r := C.dlclose(handle); r != 0 {
			err = fmt.Errorf("error closing %v", libname)
		}
	}()

	sym := C.CString("sd_pid_get_slice")
	defer C.free(unsafe.Pointer(sym))
	sd_pid_get_slice := C.dlsym(handle, sym)
	if sd_pid_get_slice == nil {
		err = fmt.Errorf("error resolving sd_pid_get_slice function")
		return
	}

	var s string
	sl := C.CString(s)
	defer C.free(unsafe.Pointer(sl))

	ret := C.my_sd_pid_get_slice(sd_pid_get_slice, 0, &sl)
	if ret < 0 {
		err = fmt.Errorf("error calling sd_pid_get_slice: %v", syscall.Errno(-ret))
		return
	}

	slice = C.GoString(sl)
	return
}

// RunningFromSystemService detects whether the current process has been invoked
// from a system service. The condition for this is whether the process is
// _not_ a user process. User processes are those running in session scopes or
// under per-user `systemd --user` instances
func RunningFromSystemService() (ret bool, err error) {
	handle, libname := getHandle()
	if handle == nil {
		// can't open libsystemd so we assume systemd is not
		// installed and we're not running from a unit file
		ret = false
		return
	}
	defer func() {
		if r := C.dlclose(handle); r != 0 {
			err = fmt.Errorf("error closing %v", libname)
		}
	}()

	sym := C.CString("sd_pid_get_owner_uid")
	defer C.free(unsafe.Pointer(sym))
	sd_pid_get_owner_uid := C.dlsym(handle, sym)
	if sd_pid_get_owner_uid == nil {
		err = fmt.Errorf("error resolving sd_pid_get_owner_uid function")
		return
	}

	var uid C.uid_t
	errno := C.my_sd_pid_get_owner_uid(sd_pid_get_owner_uid, 0, &uid)
	serrno := syscall.Errno(-errno)
	// when we're running from a unit file, sd_pid_get_owner_uid returns
	// ENOENT (systemd <220) or ENXIO (systemd >=220)
	switch {
	case errno >= 0:
		ret = false
		return
	case serrno == syscall.ENOENT, serrno == syscall.ENXIO:
		ret = true
		return
	default:
		err = fmt.Errorf("error calling sd_pid_get_owner_uid: %v", syscall.Errno(-errno))
		return
	}
}

// IsRunningSystemd checks whether the host was booted with systemd as its init
// system. This functions similar to systemd's `sd_booted(3)`: internally, it
// checks whether /run/systemd/system/ exists and is a directory.
// http://www.freedesktop.org/software/systemd/man/sd_booted.html
func IsRunningSystemd() bool {
	fi, err := os.Lstat("/run/systemd/system")
	if err != nil {
		return false
	}
	return fi.IsDir()
}
<|endoftext|>