<commit_before>package main

import (
	"bufio"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"os"
)

var (
	cmdName    = "msub"
	cmdVersion = "0.3.0"

	flagset     = flag.NewFlagSet(cmdName, flag.ContinueOnError)
	useBoundary = flagset.Bool("boundary", false, "")
	isHelp      = flagset.Bool("help", false, "")
	isVersion   = flagset.Bool("version", false, "")
)

func init() {
	flagset.SetOutput(ioutil.Discard)
	flagset.BoolVar(useBoundary, "b", false, "")
	flagset.BoolVar(isHelp, "h", false, "")
	flagset.BoolVar(isVersion, "v", false, "")
}

func usage() {
	fmt.Fprintf(os.Stderr, `
Usage: %[1]s [OPTION]... FROM TO [FILE]...
Substitute multiple words at once
by FROM and TO patterns.

Options:
  -b, --boundary    use word boundary in matcher
  -h, --help        show this help message and exit
  -v, --version     output version information and exit

Syntax:
  pattern = group , { "/" , group } ;
  group   = branch , { "," , branch } ;
  branch  = { [ "\" ] , ? unicode character ? - "/" - "," | "\/" | "\," } ;

Examples:
  %[1]s true,false false,true ./file
  %[1]s dog,cat/s cat,dog/s ~/Document/questionnaire
`[1:], cmdName)
}

func printVersion() {
	fmt.Fprintln(os.Stderr, cmdVersion)
}

func printErr(err interface{}) {
	fmt.Fprintf(os.Stderr, "%s: %s\n", cmdName, err)
}

func do(rep *Replacer, r io.Reader) error {
	b := bufio.NewScanner(r)
	for b.Scan() {
		fmt.Println(rep.Replace(b.Text()))
	}
	return b.Err()
}

func _main() int {
	if err := flagset.Parse(os.Args[1:]); err != nil {
		printErr(err)
		return 2
	}
	if *isHelp {
		usage()
		return 0
	}
	if *isVersion {
		printVersion()
		return 0
	}

	if flagset.NArg() < 1 {
		printErr("no specify FROM and TO")
		return 2
	}
	if flagset.NArg() < 2 {
		printErr("no specify TO")
		return 2
	}
	from, to := flagset.Arg(0), flagset.Arg(1)

	rep, err := NewReplacer(from, to, *useBoundary)
	if err != nil {
		printErr(err)
		return 2
	}

	var r io.Reader
	if flagset.NArg() < 3 {
		r = os.Stdin
	} else {
		var a []io.Reader
		for _, file := range flagset.Args()[2:] {
			f, err := os.Open(file)
			if err != nil {
				printErr(err)
				return 1
			}
			defer f.Close()
			a = append(a, f)
		}
		r = io.MultiReader(a...)
	}

	if err = do(rep, r); err != nil {
		printErr(err)
		return 1
	}
	return 0
}

func main() {
	e := _main()
	os.Exit(e)
}
<commit_msg>s/usage/printUsage/<commit_after>package main

import (
	"bufio"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"os"
)

var (
	cmdName    = "msub"
	cmdVersion = "0.3.0"

	flagset     = flag.NewFlagSet(cmdName, flag.ContinueOnError)
	useBoundary = flagset.Bool("boundary", false, "")
	isHelp      = flagset.Bool("help", false, "")
	isVersion   = flagset.Bool("version", false, "")
)

func init() {
	flagset.SetOutput(ioutil.Discard)
	flagset.BoolVar(useBoundary, "b", false, "")
	flagset.BoolVar(isHelp, "h", false, "")
	flagset.BoolVar(isVersion, "v", false, "")
}

func printUsage() {
	fmt.Fprintf(os.Stderr, `
Usage: %[1]s [OPTION]... FROM TO [FILE]...
Substitute multiple words at once
by FROM and TO patterns.

Options:
  -b, --boundary    use word boundary in matcher
  -h, --help        show this help message and exit
  -v, --version     output version information and exit

Syntax:
  pattern = group , { "/" , group } ;
  group   = branch , { "," , branch } ;
  branch  = { [ "\" ] , ? unicode character ? - "/" - "," | "\/" | "\," } ;

Examples:
  %[1]s true,false false,true ./file
  %[1]s dog,cat/s cat,dog/s ~/Document/questionnaire
`[1:], cmdName)
}

func printVersion() {
	fmt.Fprintln(os.Stderr, cmdVersion)
}

func printErr(err interface{}) {
	fmt.Fprintf(os.Stderr, "%s: %s\n", cmdName, err)
}

func do(rep *Replacer, r io.Reader) error {
	b := bufio.NewScanner(r)
	for b.Scan() {
		fmt.Println(rep.Replace(b.Text()))
	}
	return b.Err()
}

func _main() int {
	if err := flagset.Parse(os.Args[1:]); err != nil {
		printErr(err)
		return 2
	}
	if *isHelp {
		printUsage()
		return 0
	}
	if *isVersion {
		printVersion()
		return 0
	}

	if flagset.NArg() < 1 {
		printErr("no specify FROM and TO")
		return 2
	}
	if flagset.NArg() < 2 {
		printErr("no specify TO")
		return 2
	}
	from, to := flagset.Arg(0), flagset.Arg(1)

	rep, err := NewReplacer(from, to, *useBoundary)
	if err != nil {
		printErr(err)
		return 2
	}

	var r io.Reader
	if flagset.NArg() < 3 {
		r = os.Stdin
	} else {
		var a []io.Reader
		for _, file := range flagset.Args()[2:] {
			f, err := os.Open(file)
			if err != nil {
				printErr(err)
				return 1
			}
			defer f.Close()
			a = append(a, f)
		}
		r = io.MultiReader(a...)
	}

	if err = do(rep, r); err != nil {
		printErr(err)
		return 1
	}
	return 0
}

func main() {
	e := _main()
	os.Exit(e)
}
<|endoftext|>


<commit_before>package main

/*
 * ToTo - Go language proxy server
 * Song Hyeon Sik <blogcin@naver.com> 2015
 */

import (
	"fmt"
	"net"
	"strconv"
	"strings"
)

const (
	bufferLength = 15000
	headerLine = 30
)

type ProxyServer struct {
	port string
}

func (ps *ProxyServer) askPort() int{
	port := 0

	fmt.Print("Port : ")
	fmt.Scanf("%d", &port)

	return port
}

func (ps *ProxyServer) init(port int) net.Listener {
	ps.port = ":"
	ps.port += strconv.Itoa(port)

	server, err := net.Listen("tcp", ps.port)

	if server == nil {
		panic("init: port listening error : " + err.Error())
	}

	return server
}

func (ps *ProxyServer) acceptClient(server net.Listener) chan net.Conn{
	channel := make(chan net.Conn)

	go func() {
		for {
			client, err := server.Accept()
			if client == nil {
				fmt.Println("ps: acceptClient: Couldn't accept : ", err.Error())
				continue
			}
			channel <- client
		}

	}()
	return channel
}

func (ps *ProxyServer) connectHost(client net.Conn) {
	HeaderInfo, Datas := ps.getData(client)

	if(Datas[0] == 0 ) || (HeaderInfo == "-1"){
		return
	}
	//buffers := make([]byte, bufferLength)

	requestType, host, protocol, port := ps.parseHttpHeaderMethod(HeaderInfo)

	if(port == -1) {
		return
	}
	fmt.Println("Request Type : ", requestType)
	fmt.Println("HOST : ", host)
	fmt.Println("Protocol : ", protocol)
	fmt.Println("Port : ", port)

	connectionHost, _ := net.Dial("tcp", host + ":"+ strconv.Itoa(port))

	if requestType == "CONNECT" {
		connectionHost.Write([]byte("HTTP/1.1 200 Connection established\n"))
	} else {
		connectionHost.Write(Datas)
		fmt.Println("connectionHost.Write(Datas)")
		for {
			connectionHost.Read(Datas)
			fmt.Println("connectionHost.Read(Datas)")
			client.Write(Datas)
			fmt.Println("client.Write(Datas)")
			client.Read(Datas)
			fmt.Println("client.Read(Datas)")
			connectionHost.Write(Datas)
			fmt.Println("connectionHost.Write(Datas)")

		}
	}
	connectionHost.Close()
	return

	//io.Copy(Datas, connectionHost)
	// Get Header
	//fmt.Println(string(buffer[:]))
	//
}
/*
Get first line of Http header
 */
func (ps *ProxyServer) getData(client net.Conn) (string, []byte){

	buffer := make([]byte, bufferLength)
	client.Read(buffer)

	return ps.splitHeader(buffer)[0], buffer
}

func (ps *ProxyServer) parseHttpHeaderMethod(headerMethod string) (string, string, string, int) {
	var (
		requestType string
		host string
		protocol string
		port int
	)
	// ex: GET http://google.com/ HTTP/1.1

	temp := headerMethod[strings.Index(headerMethod, " ")+1:]
	protocol = temp[strings.Index(temp, " ")+1:]

	url := temp[:strings.Index(temp, " ")]

	i := strings.Index(url, "://")

	if i == -1 {
		fmt.Println("Uncorrect URL")
		return "", "", "", -1
	} else {
		host = url[i+3:len(url)-1]
	}

	i = strings.Index(host, ":")
	if i == -1 {
		port = 80
	} else {
		port, _ = strconv.Atoi(host[i+1:])
		host = host[:i]
	}

	i = strings.Index(host, "/")
	if i != -1 {
		host = host[:i]
	}
	requestType = headerMethod[:strings.Index(headerMethod, " ")]

	return requestType, host, protocol, port
}

func (ps *ProxyServer) splitHeader(bytearray []byte) []string {

	result := make([]string, headerLine)
	j := 0
	temp := false

	if(bytearray[0] == 0) {
		fmt.Println("ps: splitHeader: Couldn't get httpheader, zero filter")
		result[0] = string("-1")
		return result
	}

	for index, element := range bytearray {
		if(element == 13) {
			if(bytearray[index+1] == 10) {
				temp = true
			}
		}

		if(temp != true) {
			result[j] += string(element)
		}

		if(element == 10) {
			temp = false
			j += 1
		}
	}

	return result;
}

/*
func byteArrtoStr(byteArray []byte) string{
	return string(byteArray[:])
}
*/
func main() {
	proxyServer := &ProxyServer{}

	port := proxyServer.askPort()

	server := proxyServer.init(port)
	defer server.Close()

	connections := proxyServer.acceptClient(server)

	for {
		go proxyServer.connectHost(<-connections)
	}
}
<commit_msg>fix unstable data communication<commit_after>package main

/*
 * ToTo - Go language proxy server
 * Song Hyeon Sik <blogcin@naver.com> 2015
 */

import (
	"fmt"
	"net"
	"strconv"
	"strings"
	"io"
)

const (
	bufferLength = 8192
	headerLine = 30
)

type ProxyServer struct {
	port string
}

func (ps *ProxyServer) askPort() int{
	port := 0

	fmt.Print("Port : ")
	fmt.Scanf("%d", &port)

	return port
}

func (ps *ProxyServer) init(port int) net.Listener {
	ps.port = ":"
	ps.port += strconv.Itoa(port)

	server, err := net.Listen("tcp", ps.port)

	if server == nil {
		panic("init: port listening error : " + err.Error())
	}

	return server
}

func (ps *ProxyServer) acceptClient(server net.Listener) chan net.Conn{
	channel := make(chan net.Conn)

	go func() {
		for {
			client, err := server.Accept()
			if client == nil {
				fmt.Println("ps: acceptClient: Couldn't accept : ", err.Error())
				continue
			}
			channel <- client
		}

	}()
	return channel
}

func (ps *ProxyServer) test(connectionHost net.Conn, client net.Conn, Datas []byte) {
	client.Read(Datas)
	connectionHost.Write(Datas)
}

func (ps *ProxyServer) connectHost(client net.Conn) {
	HeaderInfo, Datas := ps.getData(client)
	//var i int

	if(Datas[0] == 0 ) || (HeaderInfo == "-1"){
		return
	}
	//buffers := make([]byte, bufferLength)

	requestType, host, _, port := ps.parseHttpHeaderMethod(HeaderInfo)

	if(port == -1) {
		return
	}

	connectionHost, _ := net.Dial("tcp", host + ":"+ strconv.Itoa(port))

	if requestType == "CONNECT" {
		connectionHost.Write([]byte("HTTP/1.1 200 Connection established\n"))
	} else {
		connectionHost.Write(Datas)
		go func() {
			io.Copy(connectionHost, client)
		}()
		io.Copy(client, connectionHost)
	}
	client.Close()
	connectionHost.Close()
	return
}

/*
Get first line of Http header
 */
func (ps *ProxyServer) getData(client net.Conn) (string, []byte){

	buffer := make([]byte, bufferLength)
	client.Read(buffer)

	return ps.splitHeader(buffer)[0], buffer
}

func (ps *ProxyServer) parseHttpHeaderMethod(headerMethod string) (string, string, string, int) {
	var (
		requestType string
		host string
		protocol string
		port int
	)
	// ex: GET http://google.com/ HTTP/1.1

	temp := headerMethod[strings.Index(headerMethod, " ")+1:]
	protocol = temp[strings.Index(temp, " ")+1:]

	url := temp[:strings.Index(temp, " ")]

	i := strings.Index(url, "://")

	if i == -1 {
		fmt.Println("Uncorrect URL")
		return "", "", "", -1
	} else {
		host = url[i+3:len(url)-1]
	}

	i = strings.Index(host, ":")
	if i == -1 {
		port = 80
	} else {
		port, _ = strconv.Atoi(host[i+1:])
		host = host[:i]
	}

	i = strings.Index(host, "/")
	if i != -1 {
		host = host[:i]
	}
	requestType = headerMethod[:strings.Index(headerMethod, " ")]

	return requestType, host, protocol, port
}

func (ps *ProxyServer) splitHeader(bytearray []byte) []string {

	result := make([]string, headerLine)
	j := 0
	temp := false

	if(bytearray[0] == 0) {
		fmt.Println("ps: splitHeader: Couldn't get httpheader, zero filter")
		result[0] = string("-1")
		return result
	}

	for index, element := range bytearray {
		if(element == '\r') {
			if(bytearray[index+1] == '\n') {
				temp = true
			}
		}

		if(temp != true) {
			result[j] += string(element)
		}

		if(element == '\n') {
			temp = false
			j += 1
		}
	}

	return result;
}

/*
func byteArrtoStr(byteArray []byte) string{
	return string(byteArray[:])
}
*/
func main() {
	proxyServer := &ProxyServer{}

	port := proxyServer.askPort()

	server := proxyServer.init(port)
	defer server.Close()

	connections := proxyServer.acceptClient(server)

	for {
		go proxyServer.connectHost(<-connections)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"os"
	"os/exec"
	"regexp"
	"time"

	"github.com/cloudfoundry/cli/cf/configuration/config_helpers"
	"github.com/cloudfoundry/cli/cf/configuration/core_config"
	"github.com/cloudfoundry/cli/plugin"
)

var PluginVersion string

type Application struct {
	Name   string
	Routes []struct {
		Host   string
		Domain struct {
			Name string
		}
	}
	Urls []string
}

type BlueGreenDeployPlugin struct {
	Connection plugin.CliConnection
}

func (p *BlueGreenDeployPlugin) Run(cliConnection plugin.CliConnection, args []string) {
	p.Connection = cliConnection

	if len(args) < 2 {
		fmt.Printf("App name must be provided")
		os.Exit(1)
	}

	appsInSpace, err := p.appsInCurrentSpace()
	if err != nil {
		fmt.Printf("Could not load apps in space, are you logged in? - %s", err.Error())
		os.Exit(1)
	}

	appName := args[1]
	err = p.DeleteOldAppVersions(appName, appsInSpace)
	if err != nil {
		fmt.Printf("Could not delete old app version - %s", err.Error())
		os.Exit(1)
	}

	newAppName, err := p.PushNewAppVersion(appName)
	if err != nil {
		fmt.Printf("Could not push new version - %s", err.Error())
		os.Exit(1)
	}

	fmt.Println("Deployed %s", newAppName)
}

func (p *BlueGreenDeployPlugin) GetMetadata() plugin.PluginMetadata {
	var major, minor, build int
	fmt.Sscanf(PluginVersion, "%d.%d.%d", &major, &minor, &build)

	return plugin.PluginMetadata{
		Name: "blue-green-deploy",
		Version: plugin.VersionType{
			Major: major,
			Minor: minor,
			Build: build,
		},
		Commands: []plugin.Command{
			{
				Name:     "blue-green-deploy",
				Alias:    "bgd",
				HelpText: "Zero-downtime deploys with smoke tests",
				UsageDetails: plugin.Usage{
					Usage: "blue-green-deploy APP_NAME [--integration-test TEST_SCRIPT]",
					Options: map[string]string{
						"integration-test": "The test script to run.",
					},
				},
			},
		},
	}
}

func (p *BlueGreenDeployPlugin) deleteApps(apps []Application) error {
	for _, app := range apps {
		if _, err := p.Connection.CliCommand("delete", app.Name, "-f", "-r"); err != nil {
			return err
		}
	}

	return nil
}

func (p *BlueGreenDeployPlugin) DeleteOldAppVersions(appName string, apps []Application) error {
	return p.deleteApps(FilterOldApps(appName, apps))
}

func (p *BlueGreenDeployPlugin) PushNewAppVersion(appName string) (newAppName string, err error) {
	newAppName = GenerateAppName(appName)
	_, err = p.Connection.CliCommand("push", newAppName)
	return
}

func (p *BlueGreenDeployPlugin) appsInCurrentSpace() ([]Application, error) {
	path := fmt.Sprintf("/v2/spaces/%s/summary", getSpaceGuid())

	output, err := p.Connection.CliCommandWithoutTerminalOutput("curl", path)
	if err != nil {
		return nil, err
	}

	apps := struct {
		Apps []Application
	}{}

	json.Unmarshal([]byte(output[0]), &apps)
	return apps.Apps, nil
}

func getSpaceGuid() string {
	configRepo := core_config.NewRepositoryFromFilepath(config_helpers.DefaultFilePath(), func(err error) {
		if err != nil {
			fmt.Printf("Config error: %s", err)
		}
	})

	return configRepo.SpaceFields().Guid
}

func FilterOldApps(appName string, apps []Application) (oldApps []Application) {
	r := regexp.MustCompile(fmt.Sprintf("^%s-[0-9]{14}-old$", appName))
	oldApps = []Application{}
	for _, app := range apps {
		if r.MatchString(app.Name) {
			oldApps = append(oldApps, app)
		}
	}
	return
}

func GenerateAppName(base string) string {
	return fmt.Sprintf("%s-%s", base, time.Now().Format("20060102150405"))
}

func ExtractIntegrationTestScript(args []string) string {
	f := flag.NewFlagSet("blue-green-deploy", flag.ExitOnError)
	script := f.String("integration-test", "", "")
	f.Parse(args[2:])
	return *script
}

func RunIntegrationTestScript(script, appFQDN string) (string, error) {
	out, err := exec.Command(script, appFQDN).CombinedOutput()

	return string(out), err
}

func main() {
	plugin.Start(&BlueGreenDeployPlugin{})
}
<commit_msg>we needed actual structs in tests and we don't need urls<commit_after>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"os"
	"os/exec"
	"regexp"
	"time"

	"github.com/cloudfoundry/cli/cf/configuration/config_helpers"
	"github.com/cloudfoundry/cli/cf/configuration/core_config"
	"github.com/cloudfoundry/cli/plugin"
)

var PluginVersion string

type Application struct {
	Name   string
	Routes []Route
}

type Route struct {
	Host   string
	Domain Domain
}

type Domain struct {
	Name string
}

type BlueGreenDeployPlugin struct {
	Connection plugin.CliConnection
}

func (p *BlueGreenDeployPlugin) Run(cliConnection plugin.CliConnection, args []string) {
	p.Connection = cliConnection

	if len(args) < 2 {
		fmt.Printf("App name must be provided")
		os.Exit(1)
	}

	appsInSpace, err := p.appsInCurrentSpace()
	if err != nil {
		fmt.Printf("Could not load apps in space, are you logged in? - %s", err.Error())
		os.Exit(1)
	}

	appName := args[1]
	err = p.DeleteOldAppVersions(appName, appsInSpace)
	if err != nil {
		fmt.Printf("Could not delete old app version - %s", err.Error())
		os.Exit(1)
	}

	newAppName, err := p.PushNewAppVersion(appName)
	if err != nil {
		fmt.Printf("Could not push new version - %s", err.Error())
		os.Exit(1)
	}

	fmt.Println("Deployed %s", newAppName)
}

func (p *BlueGreenDeployPlugin) GetMetadata() plugin.PluginMetadata {
	var major, minor, build int
	fmt.Sscanf(PluginVersion, "%d.%d.%d", &major, &minor, &build)

	return plugin.PluginMetadata{
		Name: "blue-green-deploy",
		Version: plugin.VersionType{
			Major: major,
			Minor: minor,
			Build: build,
		},
		Commands: []plugin.Command{
			{
				Name:     "blue-green-deploy",
				Alias:    "bgd",
				HelpText: "Zero-downtime deploys with smoke tests",
				UsageDetails: plugin.Usage{
					Usage: "blue-green-deploy APP_NAME [--integration-test TEST_SCRIPT]",
					Options: map[string]string{
						"integration-test": "The test script to run.",
					},
				},
			},
		},
	}
}

func (p *BlueGreenDeployPlugin) deleteApps(apps []Application) error {
	for _, app := range apps {
		if _, err := p.Connection.CliCommand("delete", app.Name, "-f", "-r"); err != nil {
			return err
		}
	}

	return nil
}

func (p *BlueGreenDeployPlugin) DeleteOldAppVersions(appName string, apps []Application) error {
	return p.deleteApps(FilterOldApps(appName, apps))
}

func (p *BlueGreenDeployPlugin) PushNewAppVersion(appName string) (newAppName string, err error) {
	newAppName = GenerateAppName(appName)
	_, err = p.Connection.CliCommand("push", newAppName)
	return
}

func (p *BlueGreenDeployPlugin) appsInCurrentSpace() ([]Application, error) {
	path := fmt.Sprintf("/v2/spaces/%s/summary", getSpaceGuid())

	output, err := p.Connection.CliCommandWithoutTerminalOutput("curl", path)
	if err != nil {
		return nil, err
	}

	apps := struct {
		Apps []Application
	}{}

	json.Unmarshal([]byte(output[0]), &apps)
	return apps.Apps, nil
}

func getSpaceGuid() string {
	configRepo := core_config.NewRepositoryFromFilepath(config_helpers.DefaultFilePath(), func(err error) {
		if err != nil {
			fmt.Printf("Config error: %s", err)
		}
	})

	return configRepo.SpaceFields().Guid
}

func FilterOldApps(appName string, apps []Application) (oldApps []Application) {
	r := regexp.MustCompile(fmt.Sprintf("^%s-[0-9]{14}-old$", appName))
	oldApps = []Application{}
	for _, app := range apps {
		if r.MatchString(app.Name) {
			oldApps = append(oldApps, app)
		}
	}
	return
}

func GenerateAppName(base string) string {
	return fmt.Sprintf("%s-%s", base, time.Now().Format("20060102150405"))
}

func ExtractIntegrationTestScript(args []string) string {
	f := flag.NewFlagSet("blue-green-deploy", flag.ExitOnError)
	script := f.String("integration-test", "", "")
	f.Parse(args[2:])
	return *script
}

func RunIntegrationTestScript(script, appFQDN string) (string, error) {
	out, err := exec.Command(script, appFQDN).CombinedOutput()

	return string(out), err
}

func main() {
	plugin.Start(&BlueGreenDeployPlugin{})
}
<|endoftext|>


<commit_before>// Goed is a terminal based editor.
// https://github.com/tcolar/goed
package main

import (
	"fmt"
	"log"
	"os"
	"os/exec"
	"runtime/debug"
	"runtime/pprof"
	"time"

	"github.com/tcolar/goed/actions"
	"github.com/tcolar/goed/api"
	"github.com/tcolar/goed/core"
	"github.com/tcolar/goed/ui"
	"gopkg.in/alecthomas/kingpin.v1"
)

var (
	app     = kingpin.New("goed", "A code editor")
	test    = kingpin.Flag("testterm", "Prints colors to the terminal to check them.").Bool()
	colors  = kingpin.Flag("c", "Number of colors(0,2,16,256). 0 means Detect.").Default("0").Int()
	config  = kingpin.Flag("config", "Config file.").Default("config.toml").String()
	cpuprof = kingpin.Flag("cpuprof", "Cpu profile").Default("false").Bool()
	memprof = kingpin.Flag("memprof", "Mem profile").Default("false").Bool()

	locs = kingpin.Arg("location", "location to open").Strings()
)

func main() {

	kingpin.Version(core.Version)

	kingpin.Parse()
	if *test {
		core.TestTerm()
		return
	}
	if *colors == 0 {
		*colors = core.DetectColors()
	}
	if *colors != 256 && *colors != 16 {
		*colors = 2
	}
	if *cpuprof == true {
		f, err := os.Create("prof.cprof")
		if err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}
	if *memprof == true {
		f, err := os.Create("prof.mprof")
		if err != nil {
			log.Fatal(err)
		}
		go func() {
			time.Sleep(1 * time.Minute)
			pprof.WriteHeapProfile(f)
			f.Close()
			os.Exit(0)
		}()
	}

	id := time.Now().UnixNano()

	core.Colors = *colors
	core.Bus = actions.NewActionBus()
	core.InitHome(id)
	core.ConfFile = *config
	core.Ed = ui.NewEditor()
	apiServer := api.Api{}

	defer func() {
		if fail := recover(); fail != nil {
			// writing panic to file because shell will be garbled
			fmt.Printf("Panicked with %v\n", fail)
			fmt.Printf("Writing panic to log %s \n", core.LogFile.Name())
			data := debug.Stack()
			log.Fatal(string(data))
		}
		core.Cleanup()

		core.Bus.Shutdown()

		// attempts to reset the terminal in case we left it in a bad state
		exec.Command("reset").Run()
	}()

	apiServer.Start()

	go core.Bus.Start()

	core.Ed.Start(*locs)
}
<commit_msg>Make sure goed_api is available and at the right version<commit_after>// Goed is a terminal based editor.
// https://github.com/tcolar/goed
package main

import (
	"fmt"
	"log"
	"os"
	"os/exec"
	"runtime/debug"
	"runtime/pprof"
	"strings"
	"time"

	"github.com/tcolar/goed/actions"
	"github.com/tcolar/goed/api"
	"github.com/tcolar/goed/core"
	"github.com/tcolar/goed/ui"
	"gopkg.in/alecthomas/kingpin.v1"
)

var (
	app     = kingpin.New("goed", "A code editor")
	test    = kingpin.Flag("testterm", "Prints colors to the terminal to check them.").Bool()
	colors  = kingpin.Flag("c", "Number of colors(0,2,16,256). 0 means Detect.").Default("0").Int()
	config  = kingpin.Flag("config", "Config file.").Default("config.toml").String()
	cpuprof = kingpin.Flag("cpuprof", "Cpu profile").Default("false").Bool()
	memprof = kingpin.Flag("memprof", "Mem profile").Default("false").Bool()

	locs = kingpin.Arg("location", "location to open").Strings()
)

func main() {

	kingpin.Version(core.Version)

	kingpin.Parse()
	if *test {
		core.TestTerm()
		return
	}
	if *colors == 0 {
		*colors = core.DetectColors()
	}
	if *colors != 256 && *colors != 16 {
		*colors = 2
	}
	if *cpuprof == true {
		f, err := os.Create("prof.cprof")
		if err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}
	if *memprof == true {
		f, err := os.Create("prof.mprof")
		if err != nil {
			log.Fatal(err)
		}
		go func() {
			time.Sleep(1 * time.Minute)
			pprof.WriteHeapProfile(f)
			f.Close()
			os.Exit(0)
		}()
	}

	id := time.Now().UnixNano()

	core.Colors = *colors
	core.Bus = actions.NewActionBus()
	core.InitHome(id)
	core.ConfFile = *config
	core.Ed = ui.NewEditor()
	apiServer := api.Api{}

	startupChecks()

	defer func() {
		if fail := recover(); fail != nil {
			// writing panic to file because shell will be garbled
			fmt.Printf("Panicked with %v\n", fail)
			fmt.Printf("Writing panic to log %s \n", core.LogFile.Name())
			data := debug.Stack()
			log.Fatal(string(data))
		}
		core.Cleanup()

		core.Bus.Shutdown()

		// attempts to reset the terminal in case we left it in a bad state
		exec.Command("reset").Run()
	}()

	apiServer.Start()

	go core.Bus.Start()

	core.Ed.Start(*locs)
}

func startupChecks() {
	out, err := exec.Command("goed_api", "version").CombinedOutput()
	if err != nil {
		fmt.Printf("Could not find/run goed_api : %s", out)
		os.Exit(1)
	}
	v := strings.Trim(string(out), "\n\t\r ")
	if v != core.Version {
		fmt.Printf("goed_api is not at the expected version. (got %s, want %s)",
			v, core.Version)
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2017, Sean Malloy
// 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.
//
// 3. Neither the name of the copyright holder nor the names of its contributors
//    may be used to endorse or promote products derived from this software without
//    specific prior written permission.
//
// 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 HOLDER 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 main

import (
	"bufio"
	"crypto/tls"
	"flag"
	"fmt"
	"github.com/jbogarin/go-cisco-spark/ciscospark"
	"log"
	"net/http"
	"os"
	"strings"
)

func main() {
	//
	// https://blog.komand.com/build-a-simple-cli-tool-with-golang
	//

	flag.Usage = func() {
		os.Stderr.WriteString("Commands:\n")
		os.Stderr.WriteString("  spark help [COMMAND]\n")
		os.Stderr.WriteString("  spark msg [OPTION...] MESSAGE\n")
	}

	flag.Parse()

	helpCommand := flag.NewFlagSet("help", flag.ExitOnError)

	helpCommand.Usage = func() {
		os.Stderr.WriteString("Print help messages\n")
		os.Stderr.WriteString("\n")
		os.Stderr.WriteString("SYNOPSIS\n")
		os.Stderr.WriteString("  spark help COMMAND\n")
		os.Stderr.WriteString("\n")
		os.Stderr.WriteString("EXAMPLES\n")
		os.Stderr.WriteString("  $ spark help msg\n")
	}

	msgCommand := flag.NewFlagSet("msg", flag.ExitOnError)
	msgPersonOpt := msgCommand.String("p", "", "send message to `PERSON`")
	msgSpaceOpt := msgCommand.String("s", "", "send message to `SPACE`")
	msgFileOpt := msgCommand.String("f", "", "send `FILE` as an attachment")

	msgCommand.Usage = func() {
		os.Stderr.WriteString("Send message to a person or a space\n")
		os.Stderr.WriteString("\n")
		os.Stderr.WriteString("SYNOPSIS\n")
		os.Stderr.WriteString("  spark msg -p PERSON [-f FILE] MESSAGE\n")
		os.Stderr.WriteString("  spark msg -s SPACE [-f FILE] MESSAGE\n")
		os.Stderr.WriteString("\n")
		os.Stderr.WriteString("OPTIONS\n")
		msgCommand.PrintDefaults()
		os.Stderr.WriteString("\n")
		os.Stderr.WriteString("EXAMPLES\n")
		os.Stderr.WriteString("  $ spark msg -p joe.smith@example.com 'hello world'\n")
	}

	// verify that a sub command has been provided
	if len(os.Args) < 2 {
		flag.Usage()
		os.Exit(1)
	}

	// parse CLI options for each subcommand
	switch os.Args[1] {
	case "help":
		if len(os.Args) <= 2 {
			flag.Usage()
			os.Exit(0)
		}
		helpCommand.Parse(os.Args[2:])
	case "msg":
		msgCommand.Parse(os.Args[2:])
	default:
		flag.Usage()
		os.Exit(1)
	}

	if helpCommand.Parsed() {
		if os.Args[2] == "msg" {
			msgCommand.Usage()
		} else {
			flag.Usage()
			os.Exit(1)
		}
	}

	if msgCommand.Parsed() {
		if msgCommand.Arg(0) == "" {
			// missing message
			os.Stderr.WriteString("Error: missing MESSAGE\n")
			os.Stderr.WriteString("\n")
			msgCommand.Usage()
			os.Exit(1)
		}

		if *msgPersonOpt == "" && *msgSpaceOpt == "" {
			// neither -p or -s were given
			msgCommand.Usage()
			os.Exit(1)
		}
		if *msgPersonOpt != "" && *msgSpaceOpt != "" {
			// -p and -s were both given
			msgCommand.Usage()
			os.Exit(1)
		}

		// -f is optional
		if *msgFileOpt == "" {
			if *msgPersonOpt != "" {
				// send message to a person
				fmt.Println("send message to a person")
			}

			if *msgSpaceOpt != "" {
				// send message to a space
				fmt.Println("send message to a space")
			}
		} else {
			if *msgPersonOpt != "" {
				// send file to a person
				fmt.Println("send file to a person")
			}

			if *msgSpaceOpt != "" {
				// send file to a space
				fmt.Println("send file to a space")
			}
		}

	}

	os.Exit(0)

	//
	// START: create functions to send messages to people and spaces
	//

	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client := &http.Client{Transport: tr}
	sparkClient := ciscospark.NewClient(client)

	reader := bufio.NewReader(os.Stdin)
	fmt.Print("Enter Auth Token: ")
	token, _ := reader.ReadString('\n')
	token = strings.TrimSuffix(token, "\n")
	sparkClient.Authorization = "Bearer " + token

	myPersonID := "722bb271-d7ca-4bce-a9e3-471e4412fa77"

	// POST messages - Text Message
	message := &ciscospark.MessageRequest{
		Text:       "This is a text message",
		ToPersonID: myPersonID,
	}
	newTextMessage, _, err := sparkClient.Messages.Post(message)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("POST:", newTextMessage.ID, newTextMessage.Text, newTextMessage.Created)
}
<commit_msg>Create function to send messages<commit_after>// Copyright (c) 2017, Sean Malloy
// 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.
//
// 3. Neither the name of the copyright holder nor the names of its contributors
//    may be used to endorse or promote products derived from this software without
//    specific prior written permission.
//
// 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 HOLDER 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 main

import (
	"bufio"
	"crypto/tls"
	"flag"
	"fmt"
	"github.com/jbogarin/go-cisco-spark/ciscospark"
	"log"
	"net/http"
	"os"
	"strings"
)

func send(personId string, authToken string, message string) {
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client := &http.Client{Transport: tr}
	sparkClient := ciscospark.NewClient(client)
	sparkClient.Authorization = "Bearer " + authToken

	// POST messages - Text Message
	request := &ciscospark.MessageRequest{
		Text:       message,
		ToPersonID: personId,
	}
	newTextMessage, _, err := sparkClient.Messages.Post(request)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("POST:", newTextMessage.ID, newTextMessage.Text, newTextMessage.Created)
}

func main() {
	//
	// https://blog.komand.com/build-a-simple-cli-tool-with-golang
	//

	flag.Usage = func() {
		os.Stderr.WriteString("Commands:\n")
		os.Stderr.WriteString("  spark help [COMMAND]\n")
		os.Stderr.WriteString("  spark msg [OPTION...] MESSAGE\n")
	}

	flag.Parse()

	helpCommand := flag.NewFlagSet("help", flag.ExitOnError)

	helpCommand.Usage = func() {
		os.Stderr.WriteString("Print help messages\n")
		os.Stderr.WriteString("\n")
		os.Stderr.WriteString("SYNOPSIS\n")
		os.Stderr.WriteString("  spark help COMMAND\n")
		os.Stderr.WriteString("\n")
		os.Stderr.WriteString("EXAMPLES\n")
		os.Stderr.WriteString("  $ spark help msg\n")
	}

	msgCommand := flag.NewFlagSet("msg", flag.ExitOnError)
	msgPersonOpt := msgCommand.String("p", "", "send message to `PERSON`")
	msgSpaceOpt := msgCommand.String("s", "", "send message to `SPACE`")
	msgFileOpt := msgCommand.String("f", "", "send `FILE` as an attachment")

	msgCommand.Usage = func() {
		os.Stderr.WriteString("Send message to a person or a space\n")
		os.Stderr.WriteString("\n")
		os.Stderr.WriteString("SYNOPSIS\n")
		os.Stderr.WriteString("  spark msg -p PERSON [-f FILE] MESSAGE\n")
		os.Stderr.WriteString("  spark msg -s SPACE [-f FILE] MESSAGE\n")
		os.Stderr.WriteString("\n")
		os.Stderr.WriteString("OPTIONS\n")
		msgCommand.PrintDefaults()
		os.Stderr.WriteString("\n")
		os.Stderr.WriteString("EXAMPLES\n")
		os.Stderr.WriteString("  $ spark msg -p joe.smith@example.com 'hello world'\n")
	}

	// verify that a sub command has been provided
	if len(os.Args) < 2 {
		flag.Usage()
		os.Exit(1)
	}

	// parse CLI options for each subcommand
	switch os.Args[1] {
	case "help":
		if len(os.Args) <= 2 {
			flag.Usage()
			os.Exit(0)
		}
		helpCommand.Parse(os.Args[2:])
	case "msg":
		msgCommand.Parse(os.Args[2:])
	default:
		flag.Usage()
		os.Exit(1)
	}

	if helpCommand.Parsed() {
		if os.Args[2] == "msg" {
			msgCommand.Usage()
		} else {
			flag.Usage()
			os.Exit(1)
		}
	}

	if msgCommand.Parsed() {
		if msgCommand.Arg(0) == "" {
			// missing message
			os.Stderr.WriteString("Error: missing MESSAGE\n")
			os.Stderr.WriteString("\n")
			msgCommand.Usage()
			os.Exit(1)
		}

		if *msgPersonOpt == "" && *msgSpaceOpt == "" {
			// neither -p or -s were given
			msgCommand.Usage()
			os.Exit(1)
		}
		if *msgPersonOpt != "" && *msgSpaceOpt != "" {
			// -p and -s were both given
			msgCommand.Usage()
			os.Exit(1)
		}

		// -f is optional
		if *msgFileOpt == "" {
			if *msgPersonOpt != "" {
				// send message to a person

				//
				// START: remove hard coded person id
				//
				reader := bufio.NewReader(os.Stdin)
				fmt.Print("Enter Auth Token: ")
				token, _ := reader.ReadString('\n')
				token = strings.TrimSuffix(token, "\n")
				send("722bb271-d7ca-4bce-a9e3-471e4412fa77", token, msgCommand.Arg(0))
			}

			if *msgSpaceOpt != "" {
				// send message to a space
				fmt.Println("send message to a space")
			}
		} else {
			if *msgPersonOpt != "" {
				// send file to a person
				fmt.Println("send file to a person")
			}

			if *msgSpaceOpt != "" {
				// send file to a space
				fmt.Println("send file to a space")
			}
		}

	}
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/base64"
	"errors"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"os"
	"strings"
	"time"
)

type Tokens map[string]string

func main() {
	forwardDest := os.Getenv("FORWARD_DEST")
	if forwardDest == "" {
		log.Fatalln("ENV[FORWARD_DEST] is required")
	}

	forwarder := NewForwarder(forwardDest)
	forwarder.Start()

	tokens, err := parseTokens()
	if err != nil {
		log.Fatalln("Unable to parse tokens:", err)
	}

	http.HandleFunc("/logs", func(w http.ResponseWriter, r *http.Request) {
		if r.Method != "POST" {
			http.Error(w, "Only POST is accepted", 400)
			return
		}
		if r.Header.Get("Content-Type") != "application/logplex-1" {
			http.Error(w, "Only Content-Type application/logplex-1 is accepted", 400)
			return
		}

		err := checkAuth(r, tokens)
		if err != nil {
			http.Error(w, err.Error(), 401)
			return
		}

		b, err := ioutil.ReadAll(r.Body)
		r.Body.Close()
		if err != nil {
			http.Error(w, "Invalid Request", 400)
			return
		}

		forwarder.Receive(b)
	})

	port := os.Getenv("PORT")
	if port == "" {
		log.Fatalln("ENV[PORT] is required")
	}
	if err := http.ListenAndServe(":"+port, nil); err != nil {
		log.Fatalln("Unable to start HTTP server:", err)
	}
}

func parseTokens() (Tokens, error) {
	tokens := make(Tokens)

	tokenMap := os.Getenv("TOKEN_MAP")
	if tokenMap == "" {
		return tokens, errors.New("ENV[TOKEN_MAP] is required")
	}

	for _, userAndToken := range strings.Split(tokenMap, ",") {
		userAndTokenParts := strings.SplitN(userAndToken, ":", 2)
		if len(userAndTokenParts) != 2 {
			return tokens, errors.New("ENV[TOKEN_MAP] not formatted properly")
		}
		tokens[userAndTokenParts[0]] = userAndTokenParts[1]
	}

	return tokens, nil
}

func checkAuth(r *http.Request, tokens Tokens) error {
	header := r.Header.Get("Authorization")
	if header == "" {
		return errors.New("Authorization required")
	}
	headerParts := strings.SplitN(header, " ", 2)
	if len(headerParts) != 2 {
		return errors.New("Authorization header is malformed")
	}

	method := headerParts[0]
	if method != "Basic" {
		return errors.New("Only Basic Authorization is accepted")
	}

	encodedUserPass := headerParts[1]
	decodedUserPass, err := base64.StdEncoding.DecodeString(encodedUserPass)
	if err != nil {
		return errors.New("Authorization header is malformed")
	}

	userPassParts := bytes.SplitN(decodedUserPass, []byte{':'}, 2)
	if len(userPassParts) != 2 {
		return errors.New("Authorization header is malformed")
	}

	user := userPassParts[0]
	pass := userPassParts[1]
	token, ok := tokens[string(user)]
	if !ok {
		return errors.New("Unknown user")
	}
	if token != string(pass) {
		return errors.New("Incorrect token")
	}

	return nil
}

type Forwarder struct {
	Inbox   chan []byte
	Dest    string
	c       net.Conn
	written uint64
}

func NewForwarder(dest string) *Forwarder {
	forwarder := new(Forwarder)
	forwarder.Inbox = make(chan []byte, 1024)
	forwarder.Dest = dest
	return forwarder
}

func (f *Forwarder) Receive(b []byte) {
	f.Inbox <- b
}

func (f *Forwarder) Start() {
	go f.Run()
	go f.PeriodicStats()
}

func (f *Forwarder) Run() {
	for m := range f.Inbox {
		f.write(m)
	}
}

func (f *Forwarder) PeriodicStats() {
	var connected string
	t := time.Tick(1 * time.Second)

	for {
		<-t
		connected = "no"
		if f.c != nil {
			connected = "yes"
		}
		log.Printf("ns=forwarder fn=periodic_stats at=emit connected=%s written=%d inbox_count=%d\n", connected, f.written, len(f.Inbox))
	}
}

func (f *Forwarder) connect() {
	if f.c != nil {
		return
	}

	rate := time.Tick(200 * time.Millisecond)

	for {
		log.Println("ns=forwarder fn=connect at=start")
		c, err := net.Dial("tcp", f.Dest)
		if err != nil {
			log.Printf("ns=forwarder fn=connect at=error message=%q\n", err)
			f.disconnect()
		} else {
			log.Println("ns=forwarder fn=connect at=finish")
			f.c = c
			return
		}
		<-rate
	}
}

func (f *Forwarder) disconnect() {
	if f.c != nil {
		f.c.Close()
	}
	f.c = nil
}

func (f *Forwarder) write(b []byte) {
	for {
		f.connect()
		n, err := f.c.Write(b)
		if err != nil {
			log.Println("ns=forwarder fn=write at=error message=%q\n", err)
			f.disconnect()
		} else {
			f.written += uint64(n)
			break
		}
	}
}
<commit_msg>Restructure.<commit_after>package main

import (
	"bytes"
	"encoding/base64"
	"errors"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"os"
	"strings"
	"time"
)

type Tokens map[string]string

func main() {
	forwardDest := os.Getenv("FORWARD_DEST")
	if forwardDest == "" {
		log.Fatalln("ENV[FORWARD_DEST] is required")
	}
	forwarder := NewForwarder(forwardDest)
	forwarder.Start()

	port := os.Getenv("PORT")
	if port == "" {
		log.Fatalln("ENV[PORT] is required")
	}
	tokenMap := os.Getenv("TOKEN_MAP")
	if tokenMap == "" {
		log.Fatalln("ENV[TOKEN_MAP] is required")
	}
	tokens, err := parseTokenMap(tokenMap)
	if err != nil {
		log.Fatalln("Unable to parse tokens:", err)
	}
	startHttp(port, tokens, forwarder)
}

func parseTokenMap(tokenMap string) (Tokens, error) {
	tokens := make(Tokens)

	for _, userAndToken := range strings.Split(tokenMap, ",") {
		userAndTokenParts := strings.SplitN(userAndToken, ":", 2)
		if len(userAndTokenParts) != 2 {
			return tokens, errors.New("ENV[TOKEN_MAP] not formatted properly")
		}
		tokens[userAndTokenParts[0]] = userAndTokenParts[1]
	}

	return tokens, nil
}

func startHttp(port string, tokens Tokens, forwarder *Forwarder) {
	http.HandleFunc("/logs", func(w http.ResponseWriter, r *http.Request) {
		if r.Method != "POST" {
			http.Error(w, "Only POST is accepted", 400)
			return
		}
		if r.Header.Get("Content-Type") != "application/logplex-1" {
			http.Error(w, "Only Content-Type application/logplex-1 is accepted", 400)
			return
		}

		err := checkAuth(r, tokens)
		if err != nil {
			http.Error(w, err.Error(), 401)
			return
		}

		b, err := ioutil.ReadAll(r.Body)
		r.Body.Close()
		if err != nil {
			http.Error(w, "Invalid Request", 400)
			return
		}

		forwarder.Receive(b)
	})

	if err := http.ListenAndServe(":"+port, nil); err != nil {
		log.Fatalln("Unable to start HTTP server:", err)
	}
}

func checkAuth(r *http.Request, tokens Tokens) error {
	header := r.Header.Get("Authorization")
	if header == "" {
		return errors.New("Authorization required")
	}
	headerParts := strings.SplitN(header, " ", 2)
	if len(headerParts) != 2 {
		return errors.New("Authorization header is malformed")
	}

	method := headerParts[0]
	if method != "Basic" {
		return errors.New("Only Basic Authorization is accepted")
	}

	encodedUserPass := headerParts[1]
	decodedUserPass, err := base64.StdEncoding.DecodeString(encodedUserPass)
	if err != nil {
		return errors.New("Authorization header is malformed")
	}

	userPassParts := bytes.SplitN(decodedUserPass, []byte{':'}, 2)
	if len(userPassParts) != 2 {
		return errors.New("Authorization header is malformed")
	}

	user := userPassParts[0]
	pass := userPassParts[1]
	token, ok := tokens[string(user)]
	if !ok {
		return errors.New("Unknown user")
	}
	if token != string(pass) {
		return errors.New("Incorrect token")
	}

	return nil
}

type Forwarder struct {
	Inbox   chan []byte
	Dest    string
	c       net.Conn
	written uint64
}

func NewForwarder(dest string) *Forwarder {
	forwarder := new(Forwarder)
	forwarder.Inbox = make(chan []byte, 1024)
	forwarder.Dest = dest
	return forwarder
}

func (f *Forwarder) Receive(b []byte) {
	f.Inbox <- b
}

func (f *Forwarder) Start() {
	go f.Run()
	go f.PeriodicStats()
}

func (f *Forwarder) Run() {
	for m := range f.Inbox {
		f.write(m)
	}
}

func (f *Forwarder) PeriodicStats() {
	var connected string
	t := time.Tick(1 * time.Second)

	for {
		<-t
		connected = "no"
		if f.c != nil {
			connected = "yes"
		}
		log.Printf("ns=forwarder fn=periodic_stats at=emit connected=%s written=%d inbox_count=%d\n", connected, f.written, len(f.Inbox))
	}
}

func (f *Forwarder) connect() {
	if f.c != nil {
		return
	}

	rate := time.Tick(200 * time.Millisecond)

	for {
		log.Println("ns=forwarder fn=connect at=start")
		c, err := net.Dial("tcp", f.Dest)
		if err != nil {
			log.Printf("ns=forwarder fn=connect at=error message=%q\n", err)
			f.disconnect()
		} else {
			log.Println("ns=forwarder fn=connect at=finish")
			f.c = c
			return
		}
		<-rate
	}
}

func (f *Forwarder) disconnect() {
	if f.c != nil {
		f.c.Close()
	}
	f.c = nil
}

func (f *Forwarder) write(b []byte) {
	for {
		f.connect()
		n, err := f.c.Write(b)
		if err != nil {
			log.Println("ns=forwarder fn=write at=error message=%q\n", err)
			f.disconnect()
		} else {
			f.written += uint64(n)
			break
		}
	}
}
<|endoftext|>


<commit_before>package gorequest

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strings"
)

type Options struct {
	Url    string
	Method string
	Body   string
	Json   string
	Header string
}

type SuperAgent struct {
	Url    string
	Method string
	Header map[string]string
	Type   string
	Data   map[string]interface{}
	Query  url.Values
}

func New() *SuperAgent {
	s := SuperAgent{
		Type:   "json",
		Data:   make(map[string]interface{}),
		Header: make(map[string]string)}
	return &s
}

func Post(targetUrl string) *SuperAgent {
	newReq := &SuperAgent{
		Url:    targetUrl,
		Method: "POST",
		Type:   "json",
		Header: make(map[string]string),
		Data:   make(map[string]interface{}),
		Query:  url.Values{}}
	return newReq
}

func (s *SuperAgent) Set(param string, value string) *SuperAgent {
	s.Header[param] = value
	return s
}

func (s *SuperAgent) Send(content string) *SuperAgent {
	var val map[string]interface{}
	// check if it is json format
	if err := json.Unmarshal([]byte(content), &val); err == nil {
		s.Type = "json"
		for k, v := range val {
			s.Data[k] = v
		}
	} else {
		// not json format (just normal string)
		s.Type = "form"
		queryVal, _ := url.ParseQuery(content)
		for k, _ := range queryVal {
			s.Query.Add(k, queryVal.Get(k))
		}
	}

	return s
}

func (s *SuperAgent) End() (error, *http.Response, string) {
	var (
		req  *http.Request
		err  error
		resp *http.Response
	)
	client := &http.Client{}
	if s.Method == "POST" {
		if s.Type == "json" {
			contentJson, _ := json.Marshal(s.Data)
			contentReader := bytes.NewReader(contentJson)
			req, err = http.NewRequest(s.Method, s.Url, contentReader)
			req.Header.Set("Content-Type", "application/json")
		} else if s.Type == "form" {
			req, err = http.NewRequest(s.Method, s.Url, strings.NewReader(s.Query.Encode()))
			req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
		}
	}
	for k, v := range s.Header {
		req.Header.Set(k, v)
	}
	resp, err = client.Do(req)
	if err != nil {
		return err, nil, ""
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	return nil, resp, string(body)
}

func Get(url string) (error, *http.Response, string) {
	client := &http.Client{}
	req, err := http.NewRequest("GET", url, nil)
	resp, err := client.Do(req)
	if err != nil {
		return err, nil, ""
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	return nil, resp, string(body)
}

func CustomRequest(options Options) (error, *http.Response, string) {
	fmt.Println(options)
	var (
		req  *http.Request
		err  error
		resp *http.Response
	)
	client := &http.Client{}
	if options.Method == "POST" {
		if options.Json != "" {
			content := strings.NewReader(options.Json)
			req, err = http.NewRequest(options.Method, options.Url, content)
			req.Header.Set("Content-Type", "application/json")
		}
	}
	resp, err = client.Do(req)
	if err != nil {
		return err, nil, ""
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	return nil, resp, string(body)
}

func main() {
	/*err, response, body:= Get("http://localhost:1337")
	  if err==nil && response.StatusCode == 200 {
	    fmt.Println(body)
	  }
	  fmt.Println(err, response, body)*/
	options := Options{Url: "http://localhost:1337", Method: "POST", Body: "hello", Json: `{ "hello":"hello"}`}
	CustomRequest(options)

	//s.post("/api/pet").send(`{"name":"tg"}`).end()
	Post("http://requestb.in/1f7ur5s1").
		Send(`nickname=a`).
		Set("Accept", "application/json").
		End()
	/*client:= &http.Client{}
	  req,_ := http.NewRequest("GET", "http://localhost:1337", nil)
	  req.Header.Add("Content-Type","application/json")
	  fmt.Println("main",req)
	  res, _ :=  client.Do(req)
	  fmt.Println(res.Body)
	  /*const jsonStream =`{"sn":"sn1"}`
	  reader:=strings.NewReader(jsonStream)
	  resp,_ := http.Post("http://localhost:1337", "application/json", reader)
	  defer resp.Body.Close()
	  body,_ :=ioutil.ReadAll(resp.Body)
	  fmt.Println(resp)
	  fmt.Println(string(body))*/
}
<commit_msg>Added get method to superagent<commit_after>package gorequest

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strings"
)

type Options struct {
	Url    string
	Method string
	Body   string
	Json   string
	Header string
}

type SuperAgent struct {
	Url    string
	Method string
	Header map[string]string
	Type   string
	Data   map[string]interface{}
	Query  url.Values
}

func New() *SuperAgent {
	s := SuperAgent{
		Type:   "json",
		Data:   make(map[string]interface{}),
		Header: make(map[string]string)}
	return &s
}

func Get(targetUrl string) *SuperAgent {
	newReq := &SuperAgent{
		Url:    targetUrl,
		Method: "GET",
		Header: make(map[string]string),
		Data:   make(map[string]interface{}),
		Query:  url.Values{}}
	return newReq
}

func Post(targetUrl string) *SuperAgent {
	newReq := &SuperAgent{
		Url:    targetUrl,
		Method: "POST",
		Type:   "json",
		Header: make(map[string]string),
		Data:   make(map[string]interface{}),
		Query:  url.Values{}}
	return newReq
}

func (s *SuperAgent) Set(param string, value string) *SuperAgent {
	s.Header[param] = value
	return s
}

func (s *SuperAgent) Send(content string) *SuperAgent {
	var val map[string]interface{}
	// check if it is json format
	if err := json.Unmarshal([]byte(content), &val); err == nil {
		s.Type = "json"
		for k, v := range val {
			s.Data[k] = v
		}
	} else {
		// not json format (just normal string)
		s.Type = "form"
		queryVal, _ := url.ParseQuery(content)
		for k, _ := range queryVal {
			s.Query.Add(k, queryVal.Get(k))
		}
	}

	return s
}

func (s *SuperAgent) End() (error, *http.Response, string) {
	var (
		req  *http.Request
		err  error
		resp *http.Response
	)
	client := &http.Client{}
	if s.Method == "POST" {
		if s.Type == "json" {
			contentJson, _ := json.Marshal(s.Data)
			contentReader := bytes.NewReader(contentJson)
			req, err = http.NewRequest(s.Method, s.Url, contentReader)
			req.Header.Set("Content-Type", "application/json")
		} else if s.Type == "form" {
			req, err = http.NewRequest(s.Method, s.Url, strings.NewReader(s.Query.Encode()))
			req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
		}
	} else if s.Method == "GET" {
		req, err = http.NewRequest(s.Method, s.Url, nil)
	}
	for k, v := range s.Header {
		req.Header.Set(k, v)
	}
	resp, err = client.Do(req)
	if err != nil {
		return err, nil, ""
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	return nil, resp, string(body)
}

func CustomRequest(options Options) (error, *http.Response, string) {
	fmt.Println(options)
	var (
		req  *http.Request
		err  error
		resp *http.Response
	)
	client := &http.Client{}
	if options.Method == "POST" {
		if options.Json != "" {
			content := strings.NewReader(options.Json)
			req, err = http.NewRequest(options.Method, options.Url, content)
			req.Header.Set("Content-Type", "application/json")
		}
	}
	resp, err = client.Do(req)
	if err != nil {
		return err, nil, ""
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	return nil, resp, string(body)
}

func main() {
	/*err, response, body:= Get("http://localhost:1337")
	  if err==nil && response.StatusCode == 200 {
	    fmt.Println(body)
	  }
	  fmt.Println(err, response, body)*/
	options := Options{Url: "http://localhost:1337", Method: "POST", Body: "hello", Json: `{ "hello":"hello"}`}
	CustomRequest(options)

	//s.post("/api/pet").send(`{"name":"tg"}`).end()
	Post("http://requestb.in/1f7ur5s1").
		Send(`nickname=a`).
		Set("Accept", "application/json").
		End()
	/*client:= &http.Client{}
	  req,_ := http.NewRequest("GET", "http://localhost:1337", nil)
	  req.Header.Add("Content-Type","application/json")
	  fmt.Println("main",req)
	  res, _ :=  client.Do(req)
	  fmt.Println(res.Body)
	  /*const jsonStream =`{"sn":"sn1"}`
	  reader:=strings.NewReader(jsonStream)
	  resp,_ := http.Post("http://localhost:1337", "application/json", reader)
	  defer resp.Body.Close()
	  body,_ :=ioutil.ReadAll(resp.Body)
	  fmt.Println(resp)
	  fmt.Println(string(body))*/
}
<|endoftext|>


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

package main

import (
	"fmt"
	"log"
	"os"
	"os/signal"
	"strconv"
	"strings"
	"syscall"
	"time"

	bsLog "github.com/tsuru/bs/log"
	"github.com/tsuru/bs/metric"
)

const defaultInterval = 60

var config struct {
	DockerEndpoint         string
	TsuruEndpoint          string
	TsuruToken             string
	AppNameEnvVar          string
	ProcessNameEnvVar      string
	StatusInterval         time.Duration
	SyslogListenAddress    string
	SyslogForwardAddresses []string
}

func loadConfig() {
	config.AppNameEnvVar = "TSURU_APPNAME="
	config.ProcessNameEnvVar = "TSURU_PROCESSNAME="
	config.DockerEndpoint = os.Getenv("DOCKER_ENDPOINT")
	config.TsuruEndpoint = os.Getenv("TSURU_ENDPOINT")
	config.TsuruToken = os.Getenv("TSURU_TOKEN")
	statusInterval := os.Getenv("STATUS_INTERVAL")
	parsedInterval, err := strconv.Atoi(statusInterval)
	if err != nil {
		log.Printf("[WARNING] invalid interval %q. Using the default value of %d seconds", statusInterval, defaultInterval)
		parsedInterval = defaultInterval
	}
	config.StatusInterval = time.Duration(parsedInterval) * time.Second
	config.SyslogListenAddress = os.Getenv("SYSLOG_LISTEN_ADDRESS")
	if forwarders := os.Getenv("SYSLOG_FORWARD_ADDRESSES"); forwarders != "" {
		config.SyslogForwardAddresses = strings.Split(forwarders, ",")
	} else {
		config.SyslogForwardAddresses = nil
	}
}

func statusReporter() (chan<- struct{}, <-chan struct{}) {
	abort := make(chan struct{})
	exit := make(chan struct{})
	go func(abort <-chan struct{}) {
		for {
			select {
			case <-abort:
				close(exit)
				return
			case <-time.After(config.StatusInterval):
				reportStatus()
			}
		}
	}(abort)
	return abort, exit
}

func startSignalHandler(callback func(os.Signal), signals ...os.Signal) {
	sigChan := make(chan os.Signal, 4)
	go func() {
		if signal, ok := <-sigChan; ok {
			callback(signal)
		}
	}()
	signal.Notify(sigChan, signals...)
}

func main() {
	loadConfig()
	lf := bsLog.LogForwarder{
		BindAddress:       config.SyslogListenAddress,
		ForwardAddresses:  config.SyslogForwardAddresses,
		DockerEndpoint:    config.DockerEndpoint,
		AppNameEnvVar:     config.AppNameEnvVar,
		ProcessNameEnvVar: config.ProcessNameEnvVar,
		TsuruEndpoint:     config.TsuruEndpoint,
		TsuruToken:        config.TsuruToken,
	}
	err := lf.Start()
	if err != nil {
		fmt.Printf("Unable to initialize log forwarder: %s\n", err)
		os.Exit(1)
	}
	mRunner := &metric.Runner{
		DockerEndpoint: config.DockerEndpoint,
		Interval:       defaultInterval,
	}
	mRunner.Start()
	abortReporter, reporterEnded := statusReporter()
	startSignalHandler(func(signal os.Signal) {
		close(abortReporter)
		mRunner.Stop()
	}, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT)
	<-reporterEnded
}
<commit_msg>metric: fix default running interval to 60 seconds<commit_after>// Copyright 2015 bs authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"fmt"
	"log"
	"os"
	"os/signal"
	"strconv"
	"strings"
	"syscall"
	"time"

	bsLog "github.com/tsuru/bs/log"
	"github.com/tsuru/bs/metric"
)

const defaultInterval = 60

var config struct {
	DockerEndpoint         string
	TsuruEndpoint          string
	TsuruToken             string
	AppNameEnvVar          string
	ProcessNameEnvVar      string
	StatusInterval         time.Duration
	SyslogListenAddress    string
	SyslogForwardAddresses []string
}

func loadConfig() {
	config.AppNameEnvVar = "TSURU_APPNAME="
	config.ProcessNameEnvVar = "TSURU_PROCESSNAME="
	config.DockerEndpoint = os.Getenv("DOCKER_ENDPOINT")
	config.TsuruEndpoint = os.Getenv("TSURU_ENDPOINT")
	config.TsuruToken = os.Getenv("TSURU_TOKEN")
	statusInterval := os.Getenv("STATUS_INTERVAL")
	parsedInterval, err := strconv.Atoi(statusInterval)
	if err != nil {
		log.Printf("[WARNING] invalid interval %q. Using the default value of %d seconds", statusInterval, defaultInterval)
		parsedInterval = defaultInterval
	}
	config.StatusInterval = time.Duration(parsedInterval) * time.Second
	config.SyslogListenAddress = os.Getenv("SYSLOG_LISTEN_ADDRESS")
	if forwarders := os.Getenv("SYSLOG_FORWARD_ADDRESSES"); forwarders != "" {
		config.SyslogForwardAddresses = strings.Split(forwarders, ",")
	} else {
		config.SyslogForwardAddresses = nil
	}
}

func statusReporter() (chan<- struct{}, <-chan struct{}) {
	abort := make(chan struct{})
	exit := make(chan struct{})
	go func(abort <-chan struct{}) {
		for {
			select {
			case <-abort:
				close(exit)
				return
			case <-time.After(config.StatusInterval):
				reportStatus()
			}
		}
	}(abort)
	return abort, exit
}

func startSignalHandler(callback func(os.Signal), signals ...os.Signal) {
	sigChan := make(chan os.Signal, 4)
	go func() {
		if signal, ok := <-sigChan; ok {
			callback(signal)
		}
	}()
	signal.Notify(sigChan, signals...)
}

func main() {
	loadConfig()
	lf := bsLog.LogForwarder{
		BindAddress:       config.SyslogListenAddress,
		ForwardAddresses:  config.SyslogForwardAddresses,
		DockerEndpoint:    config.DockerEndpoint,
		AppNameEnvVar:     config.AppNameEnvVar,
		ProcessNameEnvVar: config.ProcessNameEnvVar,
		TsuruEndpoint:     config.TsuruEndpoint,
		TsuruToken:        config.TsuruToken,
	}
	err := lf.Start()
	if err != nil {
		fmt.Printf("Unable to initialize log forwarder: %s\n", err)
		os.Exit(1)
	}
	mRunner := &metric.Runner{
		DockerEndpoint: config.DockerEndpoint,
		Interval:       defaultInterval * time.Second,
	}
	mRunner.Start()
	abortReporter, reporterEnded := statusReporter()
	startSignalHandler(func(signal os.Signal) {
		close(abortReporter)
		mRunner.Stop()
	}, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT)
	<-reporterEnded
}
<|endoftext|>


<commit_before>/*
Copyright 2016 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
	"flag"
	"os"
	"runtime"

	"github.com/golang/glog"

	genericapiserver "k8s.io/apiserver/pkg/server"
	"k8s.io/apiserver/pkg/util/logs"
	"k8s.io/sample-apiserver/pkg/cmd/server"
)

func main() {
	logs.InitLogs()
	defer logs.FlushLogs()

	if len(os.Getenv("GOMAXPROCS")) == 0 {
		runtime.GOMAXPROCS(runtime.NumCPU())
	}

	stopCh := genericapiserver.SetupSignalHandler()
	options := server.NewWardleServerOptions(os.Stdout, os.Stderr)
	cmd := server.NewCommandStartWardleServer(options, stopCh)
	cmd.Flags().AddGoFlagSet(flag.CommandLine)
	if err := cmd.Execute(); err != nil {
		glog.Fatal(err)
	}
}
<commit_msg>remove redudant runtime.GOMAXPROCS<commit_after>/*
Copyright 2016 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
	"flag"
	"os"

	"github.com/golang/glog"

	genericapiserver "k8s.io/apiserver/pkg/server"
	"k8s.io/apiserver/pkg/util/logs"
	"k8s.io/sample-apiserver/pkg/cmd/server"
)

func main() {
	logs.InitLogs()
	defer logs.FlushLogs()

	stopCh := genericapiserver.SetupSignalHandler()
	options := server.NewWardleServerOptions(os.Stdout, os.Stderr)
	cmd := server.NewCommandStartWardleServer(options, stopCh)
	cmd.Flags().AddGoFlagSet(flag.CommandLine)
	if err := cmd.Execute(); err != nil {
		glog.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package syaro

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"path"
)

var (
	wikiRoot    string
	templateDir = "/home/yuntan/Workspace/go/src/syaro/templates/"
)

func main() {
	// print welcome message
	fmt.Println("=== syaro wiki server ===")
	fmt.Println("Starting...")

	// set repository root
	if len(os.Args) == 2 {
		wikiRoot = os.Args[1]
	} else {
		wikiRoot = "./"
	}
	fmt.Println("WikiRoot:" + wikiRoot)

	fmt.Println("Server started. Waiting connection on port :8080")
	fmt.Println()

	// set http handler
	http.HandleFunc("/", handler)
	http.ListenAndServe(":8080", nil)
}

func handler(rw http.ResponseWriter, req *http.Request) {
	fmt.Printf("Response received (%s)\n", req.URL.Path)

	filePath := req.URL.Path

	// FIXME wrong method (ext isn't always .md)
	if path.Ext(filePath) == "" {
		filePath += ".md"
	}

	if path.Ext(filePath) == ".md" {
		fmt.Println("Rendering page...")
		filePath = path.Clean(wikiRoot + filePath)

		// load md file
		page, err := LoadPage(filePath)
		if err != nil { // file not exist, so create new page
			fmt.Println("File not exist, create new page")
			page, err = NewPage(filePath)
			if err != nil { // strange error
				http.Error(rw, err.Error(), http.StatusInternalServerError)
			}
		}

		// render html
		err = page.Render(rw)
		if err != nil {
			fmt.Println("rendering error!" + err.Error())
			http.Error(rw, err.Error(), http.StatusInternalServerError)
		}

	} else if ext := path.Ext(filePath); ext == ".css" || ext == ".js" || ext == ".ico" {
		f, err := os.Open(path.Clean(templateDir + filePath))
		if err != nil {
			fmt.Println("not found")
			http.Error(rw, err.Error(), http.StatusNotFound)
		}
		b, err := ioutil.ReadAll(f)
		if err != nil {
			fmt.Println("can't read")
			http.Error(rw, err.Error(), http.StatusInternalServerError)
		}

		fmt.Fprint(rw, string(b))
	}
}
<commit_msg>add findTemplateDir<commit_after>package syaro

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"path"
)

const (
	TEMPLATE_FILE_EXAMPLE = "page.html"
	REPOSITORY_DIR        = "syaro"
)

var (
	wikiRoot    string
	templateDir string
)

func main() {
	// print welcome message
	fmt.Println("===== Syaro Wiki Server =====")
	fmt.Println("Starting...")

	templateDir = findTemplateDir("")
	if templateDir == "" {
		fmt.Println("Error: Can't find template dir.")
		return
	}
	fmt.Println("Template dir:", templateDir)

	// set repository root
	if len(os.Args) == 2 {
		wikiRoot = os.Args[1]
	} else {
		wikiRoot = "./"
	}
	fmt.Println("WikiRoot:", wikiRoot)

	fmt.Println("Server started. Waiting connection on port :8080")
	fmt.Println()

	// set http handler
	http.HandleFunc("/", handler)
	http.ListenAndServe(":8080", nil)
}

// findTemplateDir finds template directory contains html, css, etc...
// dir is directory specified by user as template dir.
// This search several directory and return right dir.
// If not found, return empty string.
func findTemplateDir(dir string) string {
	// if template dir is specified by user, search this dir
	if dir != "" {
		_, err := os.Stat(path.Join(dir, TEMPLATE_FILE_EXAMPLE))
		// if directory isn't exist
		if err != nil {
			fmt.Println("Error: Can't find template file dir specified in argument")
			return ""
		}
		return dir
	} else { // directory isn't specified by user so search it by myself
		// first, $GOROOT/src/...
		_, err := os.Stat(path.Join(os.Getenv("GOROOT"), "src", REPOSITORY_DIR,
			"template", TEMPLATE_FILE_EXAMPLE))
		if err == nil {
			return path.Join(os.Getenv("GOROOT"), "src", REPOSITORY_DIR)
		}

		// second, /usr/local/share/syaro
		_, err = os.Stat(path.Join("/usr/local/share/syaro", "templates",
			TEMPLATE_FILE_EXAMPLE))
		if err == nil {
			return path.Join("/usr/local/share/syaro", "templates")
		}

		// can't find template dir
		return ""
	}
}

// handler is basic http request handler
func handler(rw http.ResponseWriter, req *http.Request) {
	fmt.Printf("Response received (%s)\n", req.URL.Path)

	filePath := req.URL.Path

	// FIXME wrong method (ext isn't always .md)
	if path.Ext(filePath) == "" {
		filePath += ".md"
	}

	if path.Ext(filePath) == ".md" {
		fmt.Println("Rendering page...")
		filePath = path.Clean(wikiRoot + filePath)

		// load md file
		page, err := LoadPage(filePath)
		if err != nil { // file not exist, so create new page
			fmt.Println("File not exist, create new page")
			page, err = NewPage(filePath)
			if err != nil { // strange error
				http.Error(rw, err.Error(), http.StatusInternalServerError)
			}
		}

		// render html
		err = page.Render(rw)
		if err != nil {
			fmt.Println("rendering error!", err.Error())
			http.Error(rw, err.Error(), http.StatusInternalServerError)
		}

	} else if ext := path.Ext(filePath); ext == ".css" || ext == ".js" {
		f, err := os.Open(path.Clean(templateDir + filePath))
		if err != nil {
			fmt.Println("not found")
			http.Error(rw, err.Error(), http.StatusNotFound)
		}
		b, err := ioutil.ReadAll(f)
		if err != nil {
			fmt.Println("can't read")
			http.Error(rw, err.Error(), http.StatusInternalServerError)
		}

		fmt.Fprint(rw, string(b))
	}
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"github.com/realglobe-Inc/edo/driver"
	"github.com/realglobe-Inc/edo/util"
	"github.com/realglobe-Inc/go-lib-rg/erro"
	"github.com/realglobe-Inc/go-lib-rg/rglog"
	"net/http"
	"os"
)

var exitCode = 0

func exit() {
	if exitCode != 0 {
		os.Exit(exitCode)
	}
}

func main() {
	defer exit()
	defer rglog.Flush()

	util.InitConsoleLog("github.com/realglobe-Inc")

	param, err := parseParameters(os.Args...)
	if err != nil {
		log.Err(erro.Unwrap(err))
		log.Debug(err)
		exitCode = 1
		return
	}

	util.SetupConsoleLog("github.com/realglobe-Inc", param.consLv)
	if err := util.SetupLog("github.com/realglobe-Inc", param.logType, param.logLv, param.logPath, param.fluAddr, param.fluTag); err != nil {
		log.Err(erro.Unwrap(err))
		log.Debug(err)
		exitCode = 1
		return
	}

	if err := mainCore(param); err != nil {
		err = erro.Wrap(err)
		log.Err(erro.Unwrap(err))
		log.Debug(err)
		exitCode = 1
		return
	}

	log.Info("Shut down.")
}

// system を準備する。
func mainCore(param *parameters) error {
	var taExp TaExplorer
	switch param.taExpType {
	case "file":
		taExp = NewFileTaExplorer(param.taExpPath, param.caStaleDur, param.caExpiDur)
		log.Info("Use file TA explorer " + param.taExpPath + ".")
	default:
		return erro.New("invalid TA explorer type " + param.taExpType + ".")
	}

	var taKeyReg TaKeyProvider
	switch param.taKeyRegType {
	case "file":
		taKeyReg = NewFileTaKeyProvider(param.taKeyRegPath, param.caStaleDur, param.caExpiDur)
		log.Info("Use file TA key provider " + param.taKeyRegPath + ".")
	default:
		return erro.New("invalid TA key provider type " + param.taKeyRegType + ".")
	}

	var usrNameIdx UserNameIndex
	switch param.usrNameIdxType {
	case "file":
		usrNameIdx = NewFileUserNameIndex(param.usrNameIdxPath, param.caStaleDur, param.caExpiDur)
		log.Info("Use file user name index " + param.usrNameIdxPath + ".")
	default:
		return erro.New("invalid user name index type " + param.usrNameIdxType + ".")
	}

	var usrAttrReg UserAttributeRegistry
	switch param.usrAttrRegType {
	case "file":
		usrAttrReg = NewFileUserAttributeRegistry(param.usrAttrRegPath, param.caStaleDur, param.caExpiDur)
		log.Info("Use file user attribute registry " + param.usrAttrRegPath + ".")
	default:
		return erro.New("invalid user attribute registry type " + param.usrAttrRegType + ".")
	}

	var sessCont driver.TimeLimitedKeyValueStore
	switch param.sessContType {
	case "memory":
		sessCont = driver.NewMemoryTimeLimitedKeyValueStore(param.caStaleDur, param.caExpiDur)
		log.Info("Use memory session container.")
	case "file":
		sessCont = driver.NewFileTimeLimitedKeyValueStore(param.sessContPath, keyToJsonPath, jsonPathToKey, json.Marshal, sessionUnmarshal, param.caStaleDur, param.caExpiDur)
		log.Info("Use file session container " + param.sessContPath + ".")
	default:
		return erro.New("invalid session container type " + param.sessContType + ".")
	}

	var codeCont driver.TimeLimitedKeyValueStore
	switch param.codeContType {
	case "memory":
		codeCont = driver.NewMemoryTimeLimitedKeyValueStore(param.caStaleDur, param.caExpiDur)
		log.Info("Use memory code container.")
	case "file":
		codeCont = driver.NewFileTimeLimitedKeyValueStore(param.codeContPath, keyToJsonPath, jsonPathToKey, json.Marshal, codeUnmarshal, param.caStaleDur, param.caExpiDur)
		log.Info("Use file code container " + param.codeContPath + ".")
	default:
		return erro.New("invalid code container type " + param.codeContType + ".")
	}

	var accTokenCont driver.TimeLimitedKeyValueStore
	switch param.accTokenContType {
	case "memory":
		accTokenCont = driver.NewMemoryTimeLimitedKeyValueStore(param.caStaleDur, param.caExpiDur)
		log.Info("Use memory access token container.")
	case "file":
		accTokenCont = driver.NewFileTimeLimitedKeyValueStore(param.accTokenContPath, keyToJsonPath, jsonPathToKey, json.Marshal, accessTokenUnmarshal, param.caStaleDur, param.caExpiDur)
		log.Info("Use file access token container " + param.accTokenContPath + ".")
	default:
		return erro.New("invalid access token container type " + param.accTokenContType + ".")
	}

	sys := &system{
		taExp,
		taKeyReg,
		usrNameIdx,
		usrAttrReg,
		sessCont,
		codeCont,
		accTokenCont,
		param.maxSessExpiDur,
		param.codeExpiDur,
		param.accTokenExpiDur,
		param.maxAccTokenExpiDur,
	}
	return serve(sys, param.socType, param.socPath, param.socPort, param.protType)
}

// 振り分ける。
const (
	routPagePath      = "/"
	loginPagePath     = "/login"
	logoutPagePath    = "/logout"
	beginSessPagePath = "/begin_session"
	setCookiePagePath = "/set_cookie"
	delCookiePagePath = "/delete_cookie"

	accTokenPagePath = "/access_token"

	queryPagePath = "/query"
)

func serve(sys *system, socType, socPath string, socPort int, protType string) error {
	routes := map[string]util.HandlerFunc{
		routPagePath: func(w http.ResponseWriter, r *http.Request) error {
			return routPage(sys, w, r)
		},
		loginPagePath: func(w http.ResponseWriter, r *http.Request) error {
			return loginPage(sys, w, r)
		},
		logoutPagePath: func(w http.ResponseWriter, r *http.Request) error {
			return logoutPage(sys, w, r)
		},
		beginSessPagePath: func(w http.ResponseWriter, r *http.Request) error {
			return beginSessionPage(sys, w, r)
		},
		delCookiePagePath: func(w http.ResponseWriter, r *http.Request) error {
			return deleteCookiePage(sys, w, r)
		},
		setCookiePagePath: func(w http.ResponseWriter, r *http.Request) error {
			return setCookiePage(sys, w, r)
		},
		accTokenPagePath: func(w http.ResponseWriter, r *http.Request) error {
			return accessTokenPage(sys, w, r)
		},
		queryPagePath: func(w http.ResponseWriter, r *http.Request) error {
			return queryPage(sys, w, r)
		},
	}
	return util.Serve(socType, socPath, socPort, protType, routes)
}
<commit_msg>有効期限ファイルを入れるディレクトリを指定できるようにした<commit_after>package main

import (
	"encoding/json"
	"github.com/realglobe-Inc/edo/driver"
	"github.com/realglobe-Inc/edo/util"
	"github.com/realglobe-Inc/go-lib-rg/erro"
	"github.com/realglobe-Inc/go-lib-rg/rglog"
	"net/http"
	"os"
)

var exitCode = 0

func exit() {
	if exitCode != 0 {
		os.Exit(exitCode)
	}
}

func main() {
	defer exit()
	defer rglog.Flush()

	util.InitConsoleLog("github.com/realglobe-Inc")

	param, err := parseParameters(os.Args...)
	if err != nil {
		log.Err(erro.Unwrap(err))
		log.Debug(err)
		exitCode = 1
		return
	}

	util.SetupConsoleLog("github.com/realglobe-Inc", param.consLv)
	if err := util.SetupLog("github.com/realglobe-Inc", param.logType, param.logLv, param.logPath, param.fluAddr, param.fluTag); err != nil {
		log.Err(erro.Unwrap(err))
		log.Debug(err)
		exitCode = 1
		return
	}

	if err := mainCore(param); err != nil {
		err = erro.Wrap(err)
		log.Err(erro.Unwrap(err))
		log.Debug(err)
		exitCode = 1
		return
	}

	log.Info("Shut down.")
}

// system を準備する。
func mainCore(param *parameters) error {
	var taExp TaExplorer
	switch param.taExpType {
	case "file":
		taExp = NewFileTaExplorer(param.taExpPath, param.caStaleDur, param.caExpiDur)
		log.Info("Use file TA explorer " + param.taExpPath + ".")
	default:
		return erro.New("invalid TA explorer type " + param.taExpType + ".")
	}

	var taKeyReg TaKeyProvider
	switch param.taKeyRegType {
	case "file":
		taKeyReg = NewFileTaKeyProvider(param.taKeyRegPath, param.caStaleDur, param.caExpiDur)
		log.Info("Use file TA key provider " + param.taKeyRegPath + ".")
	default:
		return erro.New("invalid TA key provider type " + param.taKeyRegType + ".")
	}

	var usrNameIdx UserNameIndex
	switch param.usrNameIdxType {
	case "file":
		usrNameIdx = NewFileUserNameIndex(param.usrNameIdxPath, param.caStaleDur, param.caExpiDur)
		log.Info("Use file user name index " + param.usrNameIdxPath + ".")
	default:
		return erro.New("invalid user name index type " + param.usrNameIdxType + ".")
	}

	var usrAttrReg UserAttributeRegistry
	switch param.usrAttrRegType {
	case "file":
		usrAttrReg = NewFileUserAttributeRegistry(param.usrAttrRegPath, param.caStaleDur, param.caExpiDur)
		log.Info("Use file user attribute registry " + param.usrAttrRegPath + ".")
	default:
		return erro.New("invalid user attribute registry type " + param.usrAttrRegType + ".")
	}

	var sessCont driver.TimeLimitedKeyValueStore
	switch param.sessContType {
	case "memory":
		sessCont = driver.NewMemoryTimeLimitedKeyValueStore(param.caStaleDur, param.caExpiDur)
		log.Info("Use memory session container.")
	case "file":
		sessCont = driver.NewFileTimeLimitedKeyValueStore(param.sessContPath, param.sessContPath+".expi", keyToJsonPath, jsonPathToKey, json.Marshal, sessionUnmarshal, param.caStaleDur, param.caExpiDur)
		log.Info("Use file session container " + param.sessContPath + ".")
	default:
		return erro.New("invalid session container type " + param.sessContType + ".")
	}

	var codeCont driver.TimeLimitedKeyValueStore
	switch param.codeContType {
	case "memory":
		codeCont = driver.NewMemoryTimeLimitedKeyValueStore(param.caStaleDur, param.caExpiDur)
		log.Info("Use memory code container.")
	case "file":
		codeCont = driver.NewFileTimeLimitedKeyValueStore(param.codeContPath, param.codeContPath+".expi", keyToJsonPath, jsonPathToKey, json.Marshal, codeUnmarshal, param.caStaleDur, param.caExpiDur)
		log.Info("Use file code container " + param.codeContPath + ".")
	default:
		return erro.New("invalid code container type " + param.codeContType + ".")
	}

	var accTokenCont driver.TimeLimitedKeyValueStore
	switch param.accTokenContType {
	case "memory":
		accTokenCont = driver.NewMemoryTimeLimitedKeyValueStore(param.caStaleDur, param.caExpiDur)
		log.Info("Use memory access token container.")
	case "file":
		accTokenCont = driver.NewFileTimeLimitedKeyValueStore(param.accTokenContPath, param.accTokenContPath+".expi", keyToJsonPath, jsonPathToKey, json.Marshal, accessTokenUnmarshal, param.caStaleDur, param.caExpiDur)
		log.Info("Use file access token container " + param.accTokenContPath + ".")
	default:
		return erro.New("invalid access token container type " + param.accTokenContType + ".")
	}

	sys := &system{
		taExp,
		taKeyReg,
		usrNameIdx,
		usrAttrReg,
		sessCont,
		codeCont,
		accTokenCont,
		param.maxSessExpiDur,
		param.codeExpiDur,
		param.accTokenExpiDur,
		param.maxAccTokenExpiDur,
	}
	return serve(sys, param.socType, param.socPath, param.socPort, param.protType)
}

// 振り分ける。
const (
	routPagePath      = "/"
	loginPagePath     = "/login"
	logoutPagePath    = "/logout"
	beginSessPagePath = "/begin_session"
	setCookiePagePath = "/set_cookie"
	delCookiePagePath = "/delete_cookie"

	accTokenPagePath = "/access_token"

	queryPagePath = "/query"
)

func serve(sys *system, socType, socPath string, socPort int, protType string) error {
	routes := map[string]util.HandlerFunc{
		routPagePath: func(w http.ResponseWriter, r *http.Request) error {
			return routPage(sys, w, r)
		},
		loginPagePath: func(w http.ResponseWriter, r *http.Request) error {
			return loginPage(sys, w, r)
		},
		logoutPagePath: func(w http.ResponseWriter, r *http.Request) error {
			return logoutPage(sys, w, r)
		},
		beginSessPagePath: func(w http.ResponseWriter, r *http.Request) error {
			return beginSessionPage(sys, w, r)
		},
		delCookiePagePath: func(w http.ResponseWriter, r *http.Request) error {
			return deleteCookiePage(sys, w, r)
		},
		setCookiePagePath: func(w http.ResponseWriter, r *http.Request) error {
			return setCookiePage(sys, w, r)
		},
		accTokenPagePath: func(w http.ResponseWriter, r *http.Request) error {
			return accessTokenPage(sys, w, r)
		},
		queryPagePath: func(w http.ResponseWriter, r *http.Request) error {
			return queryPage(sys, w, r)
		},
	}
	return util.Serve(socType, socPath, socPort, protType, routes)
}
<|endoftext|>


<commit_before><commit_msg>remove the need to symlink the migrations folder<commit_after><|endoftext|>


<commit_before>// terminal
package main

import (
	"bufio"
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"os"
	"strings"

	"github.com/decred/dcrd/dcrjson"
	"golang.org/x/crypto/ssh/terminal"
)

func execute(quit chan bool, protected *bool, cfg *config, line string, clear *bool) {
	switch line {
	case "h":
		fmt.Printf("[h]elp          print this message\n")
		fmt.Printf("[l]ist          list all available commands\n")
		fmt.Printf("[p]rotect       toggle protected mode (for passwords)\n")
		fmt.Printf("[c]lear         clear command history\n")
		fmt.Printf("[q]uit/ctrl+d   exit\n")
		fmt.Printf("Enter commands with arguments to execute them.\n")
	case "l":
		fallthrough
	case "list":
		listCommands()
	case "q":
		fallthrough
	case "quit":
		quit <- true
	case "p":
		fallthrough
	case "protect":
		if *protected {
			*protected = false
			return
		}
		*protected = true
		return
	case "c":
		fallthrough
	case "clear":
		*clear = true
	default:
		args := strings.Split(line, " ")

		if len(args) < 1 {
			usage("No command specified")
			return
		}

		// Ensure the specified method identifies a valid registered command and
		// is one of the usable types.
		listCmdMessageLocal := "Enter [l]ist to list commands"
		method := args[0]
		usageFlags, err := dcrjson.MethodUsageFlags(method)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Unrecognized command '%s'\n", method)
			fmt.Fprintln(os.Stderr, listCmdMessageLocal)
			return
		}
		if usageFlags&unusableFlags != 0 {
			fmt.Fprintf(os.Stderr, "The '%s' command can only be used via "+
				"websockets\n", method)
			fmt.Fprintln(os.Stderr, listCmdMessageLocal)
			return
		}

		// Convert remaining command line args to a slice of interface values
		// to be passed along as parameters to new command creation function.
		//
		// Since some commands, such as submitblock, can involve data which is
		// too large for the Operating System to allow as a normal command line
		// parameter, support using '-' as an argument to allow the argument
		// to be read from a stdin pipe.
		bio := bufio.NewReader(os.Stdin)
		params := make([]interface{}, 0, len(args[1:]))
		for _, arg := range args[1:] {
			if arg == "-" {
				param, err := bio.ReadString('\n')
				if err != nil && err != io.EOF {
					fmt.Fprintf(os.Stderr, "Failed to read data "+
						"from stdin: %v\n", err)
					return
				}
				if err == io.EOF && len(param) == 0 {
					fmt.Fprintln(os.Stderr, "Not enough lines "+
						"provided on stdin")
					return
				}
				param = strings.TrimRight(param, "\r\n")
				params = append(params, param)
				continue
			}

			params = append(params, arg)
		}

		// Attempt to create the appropriate command using the arguments
		// provided by the user.
		cmd, err := dcrjson.NewCmd(method, params...)
		if err != nil {
			// Show the error along with its error code when it's a
			// dcrjson.Error as it reallistcally will always be since the
			// NewCmd function is only supposed to return errors of that
			// type.
			if jerr, ok := err.(dcrjson.Error); ok {
				fmt.Fprintf(os.Stderr, "%s command: %v (code: %s)\n",
					method, err, jerr.Code)
				commandUsage(method)
				return
			}

			// The error is not a dcrjson.Error and this really should not
			// happen.  Nevertheless, fallback to just showing the error
			// if it should happen due to a bug in the package.
			fmt.Fprintf(os.Stderr, "%s command: %v\n", method, err)
			commandUsage(method)
			return
		}

		// Marshal the command into a JSON-RPC byte slice in preparation for
		// sending it to the RPC server.
		marshalledJSON, err := dcrjson.MarshalCmd(1, cmd)
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			return
		}

		// Send the JSON-RPC request to the server using the user-specified
		// connection configuration.
		result, err := sendPostRequest(marshalledJSON, cfg)
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			return
		}

		// Choose how to display the result based on its type.
		strResult := string(result)
		if strings.HasPrefix(strResult, "{") || strings.HasPrefix(strResult, "[") {
			var dst bytes.Buffer
			if err := json.Indent(&dst, result, "", "  "); err != nil {
				fmt.Fprintf(os.Stderr, "Failed to format result: %v",
					err)
				return
			}
			fmt.Println(dst.String())
			return

		} else if strings.HasPrefix(strResult, `"`) {
			var str string
			if err := json.Unmarshal(result, &str); err != nil {
				fmt.Fprintf(os.Stderr, "Failed to unmarshal result: %v",
					err)
				return
			}
			fmt.Println(str)
			return

		} else if strResult != "null" {
			fmt.Println(strResult)
		}
	}
}

func startTerminal(c *config) {
	fmt.Printf("Starting terminal mode.\n")
	fmt.Printf("Enter h for [h]elp.\n")
	fmt.Printf("Enter q for [q]uit.\n")
	done := make(chan bool)
	initState, err := terminal.GetState(0)
	protected := false
	clear := false
	if err != nil {
		fmt.Printf("error getting terminal state: %v\n", err.Error())
		return
	}

	go func() {
		terminal.MakeRaw(int(os.Stdin.Fd()))
		n := terminal.NewTerminal(os.Stdin, "> ")
		for {
			var ln string
			var err error
			if !protected {
				ln, err = n.ReadLine()
				if err != nil {
					done <- true
				}
			} else {
				ln, err = n.ReadPassword(">*")
				if err != nil {
					done <- true
				}
			}
			execute(done, &protected, c, ln, &clear)
			if clear {
				fmt.Println("Clearing history...")
				terminal.MakeRaw(int(os.Stdin.Fd()))
				n = terminal.NewTerminal(os.Stdin, "> ")
				clear = false
			}
		}
	}()
	select {
	case <-done:
		fmt.Printf("exiting...\n")
		terminal.Restore(0, initState)
		close(done)
	}
}
<commit_msg>dcrctl: fix reading from stdin in terminal mode (#294)<commit_after>// terminal
package main

import (
	"bufio"
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"os"
	"strings"

	"github.com/decred/dcrd/dcrjson"
	"golang.org/x/crypto/ssh/terminal"
)

func execute(quit chan bool, protected *bool, cfg *config, line string, clear *bool, state *terminal.State) {
	switch line {
	case "h":
		fmt.Printf("[h]elp          print this message\n")
		fmt.Printf("[l]ist          list all available commands\n")
		fmt.Printf("[p]rotect       toggle protected mode (for passwords)\n")
		fmt.Printf("[c]lear         clear command history\n")
		fmt.Printf("[q]uit/ctrl+d   exit\n")
		fmt.Printf("Enter commands with arguments to execute them.\n")
	case "l":
		fallthrough
	case "list":
		listCommands()
	case "q":
		fallthrough
	case "quit":
		quit <- true
	case "p":
		fallthrough
	case "protect":
		if *protected {
			*protected = false
			return
		}
		*protected = true
		return
	case "c":
		fallthrough
	case "clear":
		*clear = true
	default:
		args := strings.Split(line, " ")

		if len(args) < 1 {
			usage("No command specified")
			return
		}

		// Ensure the specified method identifies a valid registered command and
		// is one of the usable types.
		listCmdMessageLocal := "Enter [l]ist to list commands"
		method := args[0]
		usageFlags, err := dcrjson.MethodUsageFlags(method)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Unrecognized command '%s'\n", method)
			fmt.Fprintln(os.Stderr, listCmdMessageLocal)
			return
		}
		if usageFlags&unusableFlags != 0 {
			fmt.Fprintf(os.Stderr, "The '%s' command can only be used via "+
				"websockets\n", method)
			fmt.Fprintln(os.Stderr, listCmdMessageLocal)
			return
		}

		// Convert remaining command line args to a slice of interface values
		// to be passed along as parameters to new command creation function.
		//
		// Since some commands, such as submitblock, can involve data which is
		// too large for the Operating System to allow as a normal command line
		// parameter, support using '-' as an argument to allow the argument
		// to be read from a stdin pipe.
		bio := bufio.NewReader(os.Stdin)
		params := make([]interface{}, 0, len(args[1:]))
		for _, arg := range args[1:] {
			if arg == "-" {
				terminal.Restore(int(os.Stdin.Fd()), state)
				param, err := bio.ReadString('\n')
				state, _ = terminal.MakeRaw(int(os.Stdin.Fd()))
				if err != nil && err != io.EOF {
					fmt.Fprintf(os.Stderr, "Failed to read data "+
						"from stdin: %v\n", err)
					return
				}
				if err == io.EOF && len(param) == 0 {
					fmt.Fprintln(os.Stderr, "Not enough lines "+
						"provided on stdin")
					return
				}
				param = strings.TrimRight(param, "\r\n")
				params = append(params, param)
				continue
			}

			params = append(params, arg)
		}

		// Attempt to create the appropriate command using the arguments
		// provided by the user.
		cmd, err := dcrjson.NewCmd(method, params...)
		if err != nil {
			// Show the error along with its error code when it's a
			// dcrjson.Error as it reallistcally will always be since the
			// NewCmd function is only supposed to return errors of that
			// type.
			if jerr, ok := err.(dcrjson.Error); ok {
				fmt.Fprintf(os.Stderr, "%s command: %v (code: %s)\n",
					method, err, jerr.Code)
				commandUsage(method)
				return
			}

			// The error is not a dcrjson.Error and this really should not
			// happen.  Nevertheless, fallback to just showing the error
			// if it should happen due to a bug in the package.
			fmt.Fprintf(os.Stderr, "%s command: %v\n", method, err)
			commandUsage(method)
			return
		}

		// Marshal the command into a JSON-RPC byte slice in preparation for
		// sending it to the RPC server.
		marshalledJSON, err := dcrjson.MarshalCmd(1, cmd)
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			return
		}

		// Send the JSON-RPC request to the server using the user-specified
		// connection configuration.
		result, err := sendPostRequest(marshalledJSON, cfg)
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			return
		}

		// Choose how to display the result based on its type.
		strResult := string(result)
		if strings.HasPrefix(strResult, "{") || strings.HasPrefix(strResult, "[") {
			var dst bytes.Buffer
			if err := json.Indent(&dst, result, "", "  "); err != nil {
				fmt.Fprintf(os.Stderr, "Failed to format result: %v",
					err)
				return
			}
			fmt.Println(dst.String())
			return

		} else if strings.HasPrefix(strResult, `"`) {
			var str string
			if err := json.Unmarshal(result, &str); err != nil {
				fmt.Fprintf(os.Stderr, "Failed to unmarshal result: %v",
					err)
				return
			}
			fmt.Println(str)
			return

		} else if strResult != "null" {
			fmt.Println(strResult)
		}
	}
}

func startTerminal(c *config) {
	fmt.Printf("Starting terminal mode.\n")
	fmt.Printf("Enter h for [h]elp.\n")
	fmt.Printf("Enter q for [q]uit.\n")
	done := make(chan bool)
	initState, err := terminal.GetState(int(os.Stdin.Fd()))
	protected := false
	clear := false
	if err != nil {
		fmt.Printf("error getting terminal state: %v\n", err.Error())
		return
	}

	go func() {
		termState, _ := terminal.MakeRaw(int(os.Stdin.Fd()))
		n := terminal.NewTerminal(os.Stdin, "> ")
		for {
			var ln string
			var err error
			if !protected {
				ln, err = n.ReadLine()
				if err != nil {
					done <- true
				}
			} else {
				ln, err = n.ReadPassword(">*")
				if err != nil {
					done <- true
				}
			}
			execute(done, &protected, c, ln, &clear, termState)

			if clear {
				fmt.Println("Clearing history...")
				termState, _ = terminal.MakeRaw(int(os.Stdin.Fd()))
				n = terminal.NewTerminal(os.Stdin, "> ")
				clear = false
			}
		}
	}()
	select {
	case <-done:
		fmt.Printf("exiting...\n")
		terminal.Restore(int(os.Stdin.Fd()), initState)
		close(done)
	}
}
<|endoftext|>


<commit_before>package node

import (
	"bytes"
	"log"

	"github.com/AutoRoute/l2"
)

const protocol = 6042

var broadcast []byte

func init() {
	var err error
	broadcast, err = l2.MacToBytes("ff:ff:ff:ff:ff:ff")
	if err != nil {
		log.Fatal(err)
	}
}

// The layer two protocol takes a layer two device and returns the hash of the
// Public Key of all neighbors it can find.
type NeighborFinder interface {
	Find(l2.FrameReadWriter) <-chan NodeAddress
}

type NeighborData struct {
	pk PublicKey
}

func NewNeighborData(pk PublicKey) NeighborData {
	return NeighborData{pk}
}

func (n NeighborData) handleLink(mac []byte, frw l2.FrameReadWriter, c chan NodeAddress) {
	// Handle received packets
	defer close(c)
	for {
		frame, err := frw.ReadFrame()
		if err != nil {
			log.Printf("Failure reading from connection %v, %v", frw, err)
			return
		}
		log.Printf("%q: Received packet from %v sent to %v.\n", n.pk.Hash(), frame.Source(), frame.Destination())
		// Throw away if protocols don't match
		if frame.Type() != protocol {
			log.Printf("%q: bad protocol", n.pk.Hash())
			continue
		}
		if bytes.Equal(frame.Source(), mac) {
			log.Printf("%q: from ourselves?", n.pk.Hash())
			continue // Throw away if from me
		}
		// If the packet is to us or broadcast, record it.
		if bytes.Equal(frame.Destination(), mac) ||
			bytes.Equal(frame.Destination(), broadcast) {
			c <- NodeAddress(string(frame.Data()))
		}
		if !bytes.Equal(frame.Destination(), broadcast) {
			continue
		}
		response := l2.NewEthFrame(frame.Source(), mac, protocol, []byte(n.pk.Hash()))
		log.Printf("%q: Sending response packet %v.\n", n.pk.Hash(), frame.Source())
		err = frw.WriteFrame(response)
		if err != nil {
			log.Printf("Failure writing to connection %v, %v", frw, err)
			return
		}
	}
}

func (n NeighborData) Find(mac []byte, frw l2.FrameReadWriter) (<-chan NodeAddress, error) {
	// Send initial packet
	frame := l2.NewEthFrame(broadcast, mac, protocol, []byte(n.pk.Hash()))
	log.Printf("%q: Broadcasting packet.\n", n.pk.Hash())
	err := frw.WriteFrame(frame)
	if err != nil {
		return nil, err
	}

	c := make(chan NodeAddress)
	go n.handleLink(mac, frw, c)
	return c, nil
}
<commit_msg>Silence verbose log calls<commit_after>package node

import (
	"bytes"
	"log"

	"github.com/AutoRoute/l2"
)

const protocol = 6042

var broadcast []byte

func init() {
	var err error
	broadcast, err = l2.MacToBytes("ff:ff:ff:ff:ff:ff")
	if err != nil {
		log.Fatal(err)
	}
}

// The layer two protocol takes a layer two device and returns the hash of the
// Public Key of all neighbors it can find.
type NeighborFinder interface {
	Find(l2.FrameReadWriter) <-chan NodeAddress
}

type NeighborData struct {
	pk PublicKey
}

func NewNeighborData(pk PublicKey) NeighborData {
	return NeighborData{pk}
}

func (n NeighborData) handleLink(mac []byte, frw l2.FrameReadWriter, c chan NodeAddress) {
	// Handle received packets
	defer close(c)
	for {
		frame, err := frw.ReadFrame()
		if err != nil {
			log.Printf("Failure reading from connection %v, %v", frw, err)
			return
		}
		// Throw away if protocols don't match
		if frame.Type() != protocol {
			log.Printf("%q: bad protocol", n.pk.Hash())
			continue
		}
		if bytes.Equal(frame.Source(), mac) {
			log.Printf("%q: from ourselves?", n.pk.Hash())
			continue // Throw away if from me
		}
		// If the packet is to us or broadcast, record it.
		if bytes.Equal(frame.Destination(), mac) ||
			bytes.Equal(frame.Destination(), broadcast) {
			c <- NodeAddress(string(frame.Data()))
		}
		if !bytes.Equal(frame.Destination(), broadcast) {
			continue
		}
		response := l2.NewEthFrame(frame.Source(), mac, protocol, []byte(n.pk.Hash()))
		err = frw.WriteFrame(response)
		if err != nil {
			log.Printf("Failure writing to connection %v, %v", frw, err)
			return
		}
	}
}

func (n NeighborData) Find(mac []byte, frw l2.FrameReadWriter) (<-chan NodeAddress, error) {
	// Send initial packet
	frame := l2.NewEthFrame(broadcast, mac, protocol, []byte(n.pk.Hash()))
	err := frw.WriteFrame(frame)
	if err != nil {
		return nil, err
	}

	c := make(chan NodeAddress)
	go n.handleLink(mac, frw, c)
	return c, nil
}
<|endoftext|>