<commit_before>package main

import (
	"fmt"
	"os"
	"strconv"
	"syscall"
	"unsafe"
)

type Termios struct {
	Iflag  uint32
	Oflag  uint32
	Cflag  uint32
	Lflag  uint32
	Cc     [20]byte
	Ispeed uint32
	Ospeed uint32
}

var origTermios *Termios

func TcSetAttr(fd uintptr, termios *Termios) error {
	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TCSETS+1), uintptr(unsafe.Pointer(termios))); err != 0 {
		return err
	}
	return nil
}

func TcGetAttr(fd uintptr) (*Termios, error) {
	var termios = &Termios{}
	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, syscall.TCGETS, uintptr(unsafe.Pointer(termios))); err != 0 {
		return nil, err
	}
	return termios, nil
}

func enableRawMode() {
	origTermios, _ = TcGetAttr(os.Stdin.Fd())
	var raw Termios
	raw = *origTermios
	raw.Iflag &^= syscall.IXON | syscall.ICRNL
	raw.Oflag &^= syscall.OPOST
	raw.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.ISIG
	if e := TcSetAttr(os.Stdin.Fd(), &raw); e != nil {
		fmt.Fprintf(os.Stderr, "Problem enabling raw mode: %s\n", e)
	}
}

func disableRawMode() {
	if e := TcSetAttr(os.Stdin.Fd(), origTermios); e != nil {
		fmt.Fprintf(os.Stderr, "Problem disabling raw mode: %s\n", e)
	}
}

func main() {
	enableRawMode()
	defer disableRawMode()
	buffer := make([]byte, 1)
	for cc, err := os.Stdin.Read(buffer); buffer[0] != 'q' && err == nil && cc == 1; cc, err = os.Stdin.Read(buffer) {
		var r rune
		r = rune(buffer[0])
		if (strconv.IsPrint(r)) {
			fmt.Printf("%d  %c\n", buffer[0], r)
		} else {
			fmt.Printf("%d\n", buffer[0])
		}
	}
}
<commit_msg>Step 14 - add carriage returns to output<commit_after>package main

import (
	"fmt"
	"os"
	"strconv"
	"syscall"
	"unsafe"
)

type Termios struct {
	Iflag  uint32
	Oflag  uint32
	Cflag  uint32
	Lflag  uint32
	Cc     [20]byte
	Ispeed uint32
	Ospeed uint32
}

var origTermios *Termios

func TcSetAttr(fd uintptr, termios *Termios) error {
	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TCSETS+1), uintptr(unsafe.Pointer(termios))); err != 0 {
		return err
	}
	return nil
}

func TcGetAttr(fd uintptr) (*Termios, error) {
	var termios = &Termios{}
	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, syscall.TCGETS, uintptr(unsafe.Pointer(termios))); err != 0 {
		return nil, err
	}
	return termios, nil
}

func enableRawMode() {
	origTermios, _ = TcGetAttr(os.Stdin.Fd())
	var raw Termios
	raw = *origTermios
	raw.Iflag &^= syscall.IXON | syscall.ICRNL
	raw.Oflag &^= syscall.OPOST
	raw.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.ISIG
	if e := TcSetAttr(os.Stdin.Fd(), &raw); e != nil {
		fmt.Fprintf(os.Stderr, "Problem enabling raw mode: %s\n", e)
	}
}

func disableRawMode() {
	if e := TcSetAttr(os.Stdin.Fd(), origTermios); e != nil {
		fmt.Fprintf(os.Stderr, "Problem disabling raw mode: %s\n", e)
	}
}

func main() {
	enableRawMode()
	defer disableRawMode()
	buffer := make([]byte, 1)
	for cc, err := os.Stdin.Read(buffer); buffer[0] != 'q' && err == nil && cc == 1; cc, err = os.Stdin.Read(buffer) {
		var r rune
		r = rune(buffer[0])
		if (strconv.IsPrint(r)) {
			fmt.Printf("%d  %c\r\n", buffer[0], r)
		} else {
			fmt.Printf("%d\r\n", buffer[0])
		}
	}
}
<|endoftext|>


<commit_before>package main

// Glen Newton
// glen.newton@gmail.com

import (
	"fmt"
	"log"
	"os"
	"regexp"
	"strings"
)

type PathInfo struct {
	path      string
	isLibrary bool
}

var re = regexp.MustCompile(" +")
var filesRpmExec = []string{"rpm", "-qlvp"}

func usage(name string) {
	fmt.Println("\n\t" + name + ": Find executables and libraries in RPMs to populate PATH and LD_LIBRARY_PATH")
	fmt.Println("Usage: " + name + " <rpmfile0> ... <rpmfileN>")
	fmt.Println("\t Returns 2 lines with each of the following followed by the paths found for each:  \"LD PATH: \"   \"PATH: \" \n")
}

func main() {

	if len(os.Args) < 2 {
		usage(os.Args[0])
		return
	}

	err := checkFileNamesExist(os.Args[1:])
	if err != nil {
		return
	}

	fileLineChannel := make(chan string, 200)

	go findRpmFiles(fileLineChannel, filesRpmExec, os.Args)

	pathChannel := make(chan *PathInfo, 200)

	go makePaths(fileLineChannel, pathChannel)

	outPath := ""
	outLdLibraryPath := ""

	for path := range pathChannel {
		if path.isLibrary {
			if outLdLibraryPath != "" {
				outLdLibraryPath += ":"
			}
			outLdLibraryPath += path.path
		} else {
			if outPath != "" {
				outPath += ":"
			}
			outPath += path.path
		}
	}
	fmt.Println("PATH=" + outPath)
	fmt.Println("LD_LIBRARY_PATH=" + outLdLibraryPath)
}

func checkFileNamesExist(fileNames []string) error {
	for _, fileName := range fileNames {
		file, err := os.Open(fileName) // For read access.
		if err != nil {
			log.Print("Problem opening file: " + fileName)
			return err
		}
		fi, err := file.Stat()
		if err != nil {
			log.Print("Problem stat'ing file: " + fileName)
			return err
		}

		fm := fi.Mode()
		if !fm.IsRegular() {
			error := new(InternalError)
			error.errorString = "Is directory, needs to be file: " + fileName
			log.Print(error.errorString)
			return error
		}

		if fm.Perm().String()[7] != 'r' {
			error := new(InternalError)
			error.errorString = "Exists but unable to read: " + fileName
			log.Print(error.errorString)
			return error

		}
	}
	return nil
}

type InternalError struct {
	errorString string
}

func (ie *InternalError) Error() string {
	return "Error: " + ie.errorString
}

func findRpmFiles(fileLineChannel chan string, filesRpmExec []string, args []string) {
	// rpmFiles := []string{
	// 	"/home/newtong/work/rpms-biocluster/branches/rocks-6.1/mira/dependencies/gperftools-devel-2.0-3.el6.2.x86_64.rpm",
	// 	"/home/newtong/work/R/R2/R-2.15.1-1.x86_64.rpm",
	// 	"/home/newtong/work/R/R2/RPMS/x86_64/R2-core-2.15.1-2.x86_64.rpm",
	// 	"/home/newtong/work/rpms-biocluster/branches/rocks-6.1/sparsehash/sparsehash-2.0.2-1.noarch.rpm",
	// }

	var count = 0
	doneChannel := make(chan bool, 20)
	for i, rpmFile := range args {
		if i == 0 {
			continue
		}
		count += 1
		prog := append(filesRpmExec, rpmFile)
		runExec(prog, fileLineChannel, doneChannel)
		//fmt.Println(prog)
	}

	for i := 0; i < count; i++ {
		_ = <-doneChannel
	}

	close(fileLineChannel)
}

func makePaths(fileLineChan chan string, pathChannel chan *PathInfo) {
	pathsMap := make(map[string]bool)

	for v := range fileLineChan {
		v = re.ReplaceAllString(v, " ")
		isExecutable, isLibrary, pathString := extract(v)

		_, ok := pathsMap[pathString]
		var path *PathInfo
		if (isExecutable || isLibrary) && !ok {
			pathsMap[pathString] = true
			path = new(PathInfo)
			if isLibrary {
				path.isLibrary = true

			} else {
				path.isLibrary = false
			}

			path.path = pathString
			//fmt.Println(isExecutable, isLibrary, path, v)
			pathChannel <- path
		}
	}
	close(pathChannel)
}

func extract(p string) (bool, bool, string) {
	parts := strings.Split(p, " ")

	isExecutableFile := findExecutableFile(parts[0])

	var pathPart string
	if len(parts) == 9 {
		pathPart = parts[8]
	} else {
		if len(parts) == 8 {
			pathPart = parts[7]
			fmt.Println("#  " + p)
		} else {
			return false, false, ""
		}
	}

	isLibrary := findLibrary(pathPart)
	path := ""
	if isLibrary || isExecutableFile {
		path = makePath(pathPart)
	}

	if isLibrary {
		isExecutableFile = false
	}

	return isExecutableFile, isLibrary, path
}

func makePath(fullpath string) string {
	index := strings.LastIndex(fullpath, "/")
	if index < 0 {
		return fullpath
	}
	return fullpath[0:index]
}

func findExecutableFile(perms string) bool {
	return (perms[3] == 'x') && (perms[0] != 'd')
}

func findLibrary(path string) bool {
	return strings.HasSuffix(path, ".o") ||
		strings.HasSuffix(path, ".a") ||
		strings.HasSuffix(path, ".so") ||
		strings.Contains(path, ".so.") ||
		strings.Contains(path, ".a.")
}

func separatePaths(p []string) string {
	s := ""

	ps := string(os.PathListSeparator)
	for i, v := range p {
		if i != 0 {
			s += ps
		}
		s += v
	}
	return s
}
<commit_msg>Added flag -c which causes read on stdin for file names, one per line; good for: find . -name \*.rpm -print| rpmpaths c<commit_after>package main

// Glen Newton
// glen.newton@gmail.com

import (
	"bufio"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"regexp"
	"strings"
)

type PathInfo struct {
	path      string
	isLibrary bool
}

var re = regexp.MustCompile(" +")
var filesRpmExec = []string{"rpm", "-qlvp"}

func usage(name string) {
	fmt.Println("\n\t" + name + ": Find executables and libraries in RPMs to populate PATH and LD_LIBRARY_PATH")
	fmt.Println("Usage: " + name + " <rpmfile0> ... <rpmfileN>")
	fmt.Println("\t Returns 2 lines with each of the following followed by the paths found for each:   \"PATH: \"   \"LD PATH: \"  \n")
	flag.Usage()
}

var filesFromStdin = false

func init() {
	flag.BoolVar(&filesFromStdin, "c", filesFromStdin, "Files one per line in stdin")
	flag.Parse()
}

func main() {
	flag.Parse()

	files, err := getFileNames(filesFromStdin)
	if err != nil {
		os.Exit(42)
		return
	}

	err = checkFileNamesExist(files)
	if err != nil {
		os.Exit(42)
		return
	}

	fileLineChannel := make(chan string, 200)

	go findRpmFiles(fileLineChannel, filesRpmExec, files)

	pathChannel := make(chan *PathInfo, 200)

	go makePaths(fileLineChannel, pathChannel)

	outPath := ""
	outLdLibraryPath := ""

	for path := range pathChannel {
		if path.isLibrary {
			if outLdLibraryPath != "" {
				outLdLibraryPath += ":"
			}
			outLdLibraryPath += path.path
		} else {
			if outPath != "" {
				outPath += ":"
			}
			outPath += path.path
		}
	}
	fmt.Println("PATH=" + outPath)
	fmt.Println("LD_LIBRARY_PATH=" + outLdLibraryPath)
}

func checkFileNamesExist(fileNames []string) error {
	for _, fileName := range fileNames {
		file, err := os.Open(fileName) // For read access.
		if err != nil {
			log.Print("Problem opening file: [" + fileName + "]")
			return err
		}
		fi, err := file.Stat()
		if err != nil {
			log.Print("Problem stat'ing file: [" + fileName + "]")
			return err
		}

		fm := fi.Mode()
		if !fm.IsRegular() {
			error := new(InternalError)
			error.errorString = "Is directory, needs to be file: " + fileName
			log.Print(error.errorString)
			return error
		}

		if fm.Perm().String()[7] != 'r' {
			error := new(InternalError)
			error.errorString = "Exists but unable to read: " + fileName
			log.Print(error.errorString)
			return error

		}
	}
	return nil
}

type InternalError struct {
	errorString string
}

func (ie *InternalError) Error() string {
	return "Error: " + ie.errorString
}

func findRpmFiles(fileLineChannel chan string, filesRpmExec []string, args []string) {
	var count = 0
	doneChannel := make(chan bool, 20)
	for _, rpmFile := range args {
		count += 1
		prog := append(filesRpmExec, rpmFile)
		runExec(prog, fileLineChannel, doneChannel)
	}

	for i := 0; i < count; i++ {
		_ = <-doneChannel
	}

	close(fileLineChannel)
}

func makePaths(fileLineChan chan string, pathChannel chan *PathInfo) {
	pathsMap := make(map[string]bool)

	for v := range fileLineChan {
		v = re.ReplaceAllString(v, " ")
		isExecutable, isLibrary, pathString := extract(v)

		_, ok := pathsMap[pathString]
		var path *PathInfo
		if (isExecutable || isLibrary) && !ok {
			pathsMap[pathString] = true
			path = new(PathInfo)
			if isLibrary {
				path.isLibrary = true

			} else {
				path.isLibrary = false
			}
			path.path = pathString
			pathChannel <- path
		}
	}
	close(pathChannel)
}

func extract(p string) (bool, bool, string) {
	parts := strings.Split(p, " ")

	isExecutableFile := findExecutableFile(parts[0])

	var pathPart string
	if len(parts) == 9 {
		pathPart = parts[8]
	} else {
		// bug in rpm...
		if len(parts) == 8 {
			pathPart = parts[7]
			fmt.Println("#  " + p)
		} else {
			return false, false, ""
		}
	}

	isLibrary := findLibrary(pathPart)
	path := ""
	if isLibrary || isExecutableFile {
		path = makePath(pathPart)
	}

	if isLibrary {
		isExecutableFile = false
	}

	return isExecutableFile, isLibrary, path
}

func getFileNames(filesFromStdin bool) ([]string, error) {
	var files []string
	if !filesFromStdin {
		// read files line by line from stdin
		files = flag.Args()[0:]
	} else {
		// or command line
		reader := bufio.NewReader(os.Stdin)
		for {
			line, err := reader.ReadString('\n')

			if err != nil {
				if err == io.EOF {
					break
				} else {
					log.Fatal(err)
					return nil, err
				}
			}
			files = append(files, line[0:len(line)-1])
		}
	}
	return files, nil
}

func makePath(fullpath string) string {
	index := strings.LastIndex(fullpath, "/")
	if index < 0 {
		return fullpath
	}
	return fullpath[0:index]
}

func findExecutableFile(perms string) bool {
	return (perms[3] == 'x') && (perms[0] != 'd')
}

func findLibrary(path string) bool {
	return strings.HasSuffix(path, ".o") ||
		strings.HasSuffix(path, ".a") ||
		strings.HasSuffix(path, ".so") ||
		strings.Contains(path, ".so.") ||
		strings.Contains(path, ".a.")
}

func separatePaths(p []string) string {
	s := ""

	ps := string(os.PathListSeparator)
	for i, v := range p {
		if i != 0 {
			s += ps
		}
		s += v
	}
	return s
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"log"
	"os"
	"time"

	"github.com/ninjasphere/gatt"
	"github.com/ninjasphere/go-ninja/api"
	nconfig "github.com/ninjasphere/go-ninja/config"
	nlog "github.com/ninjasphere/go-ninja/logger"
	"github.com/ninjasphere/go-ninja/support"
	"github.com/ninjasphere/sphere-client/client"
	"github.com/ninjasphere/sphere-go-led-controller/model"
	"github.com/ninjasphere/sphere-go-led-controller/util"
)

const WirelessNetworkInterface = "wlan0"

// consider the wifi to be invalid after this timeout
const WirelessStaleTimeout = time.Second * 30 // FIXME: INCREASE THIS. a few minutes at least when not in testing.

var firewallHook = flag.Bool("firewall-hook", false, "Sets up the firewall based on configuration options, and nothing else.")
var factoryReset = false
var imagesDir = ""

// factoryReset - we can't use anything that requires MQTT in this mode

var logger = nlog.GetLogger("sphere-setup")

func main() {
	// ap0 adhoc/hostap management
	flag.BoolVar(&factoryReset, "factory-reset", false, "Run in factory reset mode.")
	flag.StringVar(&imagesDir, "images", "/opt/ninjablocks/drivers/sphere-go-led-controller/images", "The location of the images directory.")

	go func() {
		support.WaitUntilSignal()
	}()

	config := LoadConfig("/etc/opt/ninja/setup-assistant.conf")
	apManager := NewAccessPointManager(config)

	flag.Parse()

	if *firewallHook {
		logger.Debugf("Setting ip firewall rules...")
		apManager.SetupFirewall()
		return
	}

	util.SetImageDir(imagesDir)
	var pairing_ui ConsolePairingUI
	var controlChecker *ControlChecker

	restartHeartbeat := false

	if err := EnsureBLEIsUp(time.Second * 30); err != nil {
		logger.Errorf("BLE failed to start: %s", err)
	}

	startResetMonitor(func(m *model.ResetMode) {
		if pairing_ui == nil || controlChecker == nil {
			return
		}
		if m.Mode == "none" {
			if restartHeartbeat {
				// only restart the heartbeat if we stopped it previously
				controlChecker.StartHeartbeat()
			}
		} else {
			restartHeartbeat = controlChecker.StopHeartbeat()
			pairing_ui.DisplayResetMode(m)
		}
	})

	apManager.WriteAPConfig()
	if config.Wireless_Host.Always_Active {
		apManager.StartHostAP()
	} else {
		apManager.StopHostAP()
	}

	// wlan0 client management
	wifi_manager, err := NewWifiManager(WirelessNetworkInterface)
	if err != nil {
		log.Fatal("Could not setup manager for wlan0, does the interface exist?: %v", err)
	}
	defer wifi_manager.Cleanup()

	// When in reset mode, this will talk to the led matrix directly,
	// otherwise, it will use sphere-go-led-controller via mqtt.
	pairing_ui, err = NewPairingUI()
	if err != nil {
		log.Fatal("Could not setup ninja connection")
	}

	// This name is sent in the BLE advertising packet,
	// and is used by the phone to see that this is a
	// sphere, and if it is in factory reset mode.
	serviceName := "ninjasphere"
	if factoryReset {
		serviceName = "resetsphere"
	}

	srv := &gatt.Server{
		Name: serviceName,
		Connect: func(c gatt.Conn) {
			logger.Infof("BLE Connect")
			//pairing_ui.DisplayIcon("ble-connected.gif")
		},
		Disconnect: func(c gatt.Conn) {
			logger.Infof("BLE Disconnect")
			//pairing_ui.DisplayIcon("ble-disconnected.gif")
		},
		StateChange: func(state string) {
			logger.Infof("BLE State Change: %s", state)
		},
	}

	var conn *ninja.Connection

	if !factoryReset {

		conn, err = ninja.Connect("sphere-setup-assistant-updates")

		if err != nil {
			logger.FatalErrorf(err, "Failed to connect to mqtt")
		}
	}

	// start by registering the RPC functions that will be accessible
	// once the client has authenticated
	// We pass in the ble server so that we can close the connection once the updates are installed
	// (THIS SHOULD HAPPEN OVER WIFI INSTEAD!)
	rpc_router := GetSetupRPCRouter(conn, wifi_manager, srv, pairing_ui)

	StartHTTPServer(conn, wifi_manager, srv, pairing_ui)

	auth_handler := new(OneTimeAuthHandler)
	auth_handler.Init("spheramid")

	controlChecker = NewControlChecker(pairing_ui)

	RegisterSecuredRPCService(srv, rpc_router, auth_handler, pairing_ui)

	// Start the server
	//log.Println("Starting setup assistant...");
	//log.Fatal(srv.AdvertiseAndServe())

	states := wifi_manager.WatchState()

	//wifi_manager.WifiConfigured()

	var wireless_stale *time.Timer

	is_serving_pairer := false

	// start by forcing the state to Disconnected.
	// reloading the configuration in wpa_supplicant will also force this,
	// but we need to do it here in case we are already disconnected
	states <- WifiStateDisconnected
	wifi_manager.Controller.ReloadConfiguration()

	handleBadWireless := func() {
		logger.Warningf("Wireless is stale! Invalid SSID, router down, or not in range.")

		if !is_serving_pairer {
			is_serving_pairer = true
			colorHintSent = false

			// If we aren't paired, update the avahi service
			if !nconfig.IsPaired() {
				client.UpdateSphereAvahiService(false, false)
			}

			// Show the phone pairing icon only if we don't always have AP
			if !config.Wireless_Host.Always_Active {
				pairing_ui.DisableControl()
				pairing_ui.DisplayIcon("phone-fade.gif")
			}

			logger.Infof("Launching BLE pairing assistant...")
			go func() {
				err := srv.AdvertiseAndServe()
				if err != nil {
					logger.Infof("Failed to advertise and serve OR finished serving: %v", err)
				}
				is_serving_pairer = false
			}()

			// and if the hostap isn't normally active, make it active
			if !config.Wireless_Host.Always_Active {
				logger.Infof("Launching AdHoc pairing assistant...")
				apManager.StartHostAP()
			}
		}
	}

	wifi_configured, _ := wifi_manager.WifiConfigured()
	if !wifi_configured {
		// when wireless isn't configured at all, automatically start doing this, don't wait for staleness
		handleBadWireless()
	}

	if config.Wireless_Host.Enables_Control {
		// the wireless AP causes control to be enabled, so we just start the heartbeat immediately
		controlChecker.StartHeartbeat()
	}

	for {
		state := <-states
		logger.Infof("State: %v", state)

		switch state {
		case WifiStateConnected:
			if wireless_stale != nil {
				wireless_stale.Stop()
			}
			wireless_stale = nil
			logger.Infof("Connected and attempting to get IP.")

			/*if !config.Wireless_Host.Enables_Control {
				// if the wireless AP mode hasn't already enabled normal control, then enable it now that wifi works
				controlChecker.StartHeartbeat()
			}*/

			if is_serving_pairer {
				is_serving_pairer = false

				// Sleep for 10s before killing ble, just in case we're using it
				go func() {
					time.Sleep(time.Second * 10)
					srv.Close()
				}()

				// and if the hostap isn't normally active, turn it off again
				if !config.Wireless_Host.Always_Active {
					logger.Infof("Terminating AdHoc pairing assistant.")
					go func() {
						// Sleep for 20 sec before killing ap, just in case we're using it to set up!
						time.Sleep(time.Second * 20)
						apManager.StopHostAP()
					}()
				}
			}

			if factoryReset {
				// if the app provided credentials, then we need to wait for app to acknowledge the connected state
				// before we exit otherwise it may not receive the response. So, we configure a callback which
				// will be called once the app as indicated that it has seen the connected state.
				wifi_manager.OnAcknowledgment(func() {
					logger.Infof("Network connected. Quitting.")
					os.Exit(0)
				})
			}

		case WifiStateDisconnected:
			if wireless_stale == nil {
				wireless_stale = time.AfterFunc(WirelessStaleTimeout, handleBadWireless)
			}

		case WifiStateInvalidKey:
			if wireless_stale == nil {
				wireless_stale = time.AfterFunc(WirelessStaleTimeout, handleBadWireless)
			}
			wifi_configured, _ = wifi_manager.WifiConfigured()
			if wifi_configured {
				// not stale, we actually know the key is wrong
				// FIXME: report back to the user! for now we're just going to let staleness timeout
				/*if wireless_stale != nil {
					wireless_stale.Stop()
				}
				wireless_stale = nil*/

				logger.Warningf("Wireless key is invalid!")
			}
		}
	}
}
<commit_msg>Re-enable led control if bad wifi gets better again<commit_after>package main

import (
	"flag"
	"log"
	"os"
	"time"

	"github.com/ninjasphere/gatt"
	"github.com/ninjasphere/go-ninja/api"
	nconfig "github.com/ninjasphere/go-ninja/config"
	nlog "github.com/ninjasphere/go-ninja/logger"
	"github.com/ninjasphere/go-ninja/support"
	"github.com/ninjasphere/sphere-client/client"
	"github.com/ninjasphere/sphere-go-led-controller/model"
	"github.com/ninjasphere/sphere-go-led-controller/util"
)

const WirelessNetworkInterface = "wlan0"

// consider the wifi to be invalid after this timeout
const WirelessStaleTimeout = time.Second * 30 // FIXME: INCREASE THIS. a few minutes at least when not in testing.

var firewallHook = flag.Bool("firewall-hook", false, "Sets up the firewall based on configuration options, and nothing else.")
var factoryReset = false
var imagesDir = ""

// factoryReset - we can't use anything that requires MQTT in this mode

var logger = nlog.GetLogger("sphere-setup")

func main() {
	// ap0 adhoc/hostap management
	flag.BoolVar(&factoryReset, "factory-reset", false, "Run in factory reset mode.")
	flag.StringVar(&imagesDir, "images", "/opt/ninjablocks/drivers/sphere-go-led-controller/images", "The location of the images directory.")

	go func() {
		support.WaitUntilSignal()
	}()

	config := LoadConfig("/etc/opt/ninja/setup-assistant.conf")
	apManager := NewAccessPointManager(config)

	flag.Parse()

	if *firewallHook {
		logger.Debugf("Setting ip firewall rules...")
		apManager.SetupFirewall()
		return
	}

	util.SetImageDir(imagesDir)
	var pairing_ui ConsolePairingUI
	var controlChecker *ControlChecker

	restartHeartbeat := false

	if err := EnsureBLEIsUp(time.Second * 30); err != nil {
		logger.Errorf("BLE failed to start: %s", err)
	}

	startResetMonitor(func(m *model.ResetMode) {
		if pairing_ui == nil || controlChecker == nil {
			return
		}
		if m.Mode == "none" {
			if restartHeartbeat {
				// only restart the heartbeat if we stopped it previously
				controlChecker.StartHeartbeat()
			}
		} else {
			restartHeartbeat = controlChecker.StopHeartbeat()
			pairing_ui.DisplayResetMode(m)
		}
	})

	apManager.WriteAPConfig()
	if config.Wireless_Host.Always_Active {
		apManager.StartHostAP()
	} else {
		apManager.StopHostAP()
	}

	// wlan0 client management
	wifi_manager, err := NewWifiManager(WirelessNetworkInterface)
	if err != nil {
		log.Fatal("Could not setup manager for wlan0, does the interface exist?: %v", err)
	}
	defer wifi_manager.Cleanup()

	// When in reset mode, this will talk to the led matrix directly,
	// otherwise, it will use sphere-go-led-controller via mqtt.
	pairing_ui, err = NewPairingUI()
	if err != nil {
		log.Fatal("Could not setup ninja connection")
	}

	// This name is sent in the BLE advertising packet,
	// and is used by the phone to see that this is a
	// sphere, and if it is in factory reset mode.
	serviceName := "ninjasphere"
	if factoryReset {
		serviceName = "resetsphere"
	}

	srv := &gatt.Server{
		Name: serviceName,
		Connect: func(c gatt.Conn) {
			logger.Infof("BLE Connect")
			//pairing_ui.DisplayIcon("ble-connected.gif")
		},
		Disconnect: func(c gatt.Conn) {
			logger.Infof("BLE Disconnect")
			//pairing_ui.DisplayIcon("ble-disconnected.gif")
		},
		StateChange: func(state string) {
			logger.Infof("BLE State Change: %s", state)
		},
	}

	var conn *ninja.Connection

	if !factoryReset {

		conn, err = ninja.Connect("sphere-setup-assistant-updates")

		if err != nil {
			logger.FatalErrorf(err, "Failed to connect to mqtt")
		}
	}

	// start by registering the RPC functions that will be accessible
	// once the client has authenticated
	// We pass in the ble server so that we can close the connection once the updates are installed
	// (THIS SHOULD HAPPEN OVER WIFI INSTEAD!)
	rpc_router := GetSetupRPCRouter(conn, wifi_manager, srv, pairing_ui)

	StartHTTPServer(conn, wifi_manager, srv, pairing_ui)

	auth_handler := new(OneTimeAuthHandler)
	auth_handler.Init("spheramid")

	controlChecker = NewControlChecker(pairing_ui)

	RegisterSecuredRPCService(srv, rpc_router, auth_handler, pairing_ui)

	// Start the server
	//log.Println("Starting setup assistant...");
	//log.Fatal(srv.AdvertiseAndServe())

	states := wifi_manager.WatchState()

	//wifi_manager.WifiConfigured()

	var wireless_stale *time.Timer

	is_serving_pairer := false

	// start by forcing the state to Disconnected.
	// reloading the configuration in wpa_supplicant will also force this,
	// but we need to do it here in case we are already disconnected
	states <- WifiStateDisconnected
	wifi_manager.Controller.ReloadConfiguration()

	badWifiMessage := false

	handleBadWireless := func() {
		logger.Warningf("Wireless is stale! Invalid SSID, router down, or not in range.")

		if !is_serving_pairer {
			is_serving_pairer = true
			colorHintSent = false

			// If we aren't paired, update the avahi service
			if !nconfig.IsPaired() {
				client.UpdateSphereAvahiService(false, false)
			}

			// Show the phone pairing icon only if we don't always have AP
			if !config.Wireless_Host.Always_Active {
				pairing_ui.DisableControl()
				pairing_ui.DisplayIcon("phone-fade.gif")
				if wifi_manager.WifiConfigured() {
					badWifiMessage = true
				}
			}

			logger.Infof("Launching BLE pairing assistant...")
			go func() {
				err := srv.AdvertiseAndServe()
				if err != nil {
					logger.Infof("Failed to advertise and serve OR finished serving: %v", err)
				}
				is_serving_pairer = false
			}()

			// and if the hostap isn't normally active, make it active
			if !config.Wireless_Host.Always_Active {
				logger.Infof("Launching AdHoc pairing assistant...")
				apManager.StartHostAP()
			}
		}
	}

	wifi_configured, _ := wifi_manager.WifiConfigured()
	if !wifi_configured {
		// when wireless isn't configured at all, automatically start doing this, don't wait for staleness
		handleBadWireless()
	}

	if config.Wireless_Host.Enables_Control {
		// the wireless AP causes control to be enabled, so we just start the heartbeat immediately
		controlChecker.StartHeartbeat()
	}

	for {
		state := <-states
		logger.Infof("State: %v", state)

		switch state {
		case WifiStateConnected:
			if wireless_stale != nil {
				wireless_stale.Stop()
			}
			wireless_stale = nil
			logger.Infof("Connected and attempting to get IP.")

			/*if !config.Wireless_Host.Enables_Control {
				// if the wireless AP mode hasn't already enabled normal control, then enable it now that wifi works
				controlChecker.StartHeartbeat()
			}*/

			if badWifiMessage {
				badWifiMessage = false
				pairing_ui.EnableControl()
			}

			if is_serving_pairer {
				is_serving_pairer = false

				// Sleep for 10s before killing ble, just in case we're using it
				go func() {
					time.Sleep(time.Second * 10)
					srv.Close()
				}()

				// and if the hostap isn't normally active, turn it off again
				if !config.Wireless_Host.Always_Active {
					logger.Infof("Terminating AdHoc pairing assistant.")
					go func() {
						// Sleep for 20 sec before killing ap, just in case we're using it to set up!
						time.Sleep(time.Second * 20)
						apManager.StopHostAP()
					}()
				}
			}

			if factoryReset {
				// if the app provided credentials, then we need to wait for app to acknowledge the connected state
				// before we exit otherwise it may not receive the response. So, we configure a callback which
				// will be called once the app as indicated that it has seen the connected state.
				wifi_manager.OnAcknowledgment(func() {
					logger.Infof("Network connected. Quitting.")
					os.Exit(0)
				})
			}

		case WifiStateDisconnected:
			if wireless_stale == nil {
				wireless_stale = time.AfterFunc(WirelessStaleTimeout, handleBadWireless)
			}

		case WifiStateInvalidKey:
			if wireless_stale == nil {
				wireless_stale = time.AfterFunc(WirelessStaleTimeout, handleBadWireless)
			}
			wifi_configured, _ = wifi_manager.WifiConfigured()
			if wifi_configured {
				// not stale, we actually know the key is wrong
				// FIXME: report back to the user! for now we're just going to let staleness timeout
				/*if wireless_stale != nil {
					wireless_stale.Stop()
				}
				wireless_stale = nil*/

				logger.Warningf("Wireless key is invalid!")
			}
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"unicode"

	"github.com/rjeczalik/notify"

	"bigoh.co.uk/language-tool/formats"
	"bigoh.co.uk/language-tool/replacer"
	"bigoh.co.uk/language-tool/strings"
)

func main() {
	rootFolder := "/Users/neilmoore67/tmp/foo"

	replacer := replacer.NewMakerRegistry(rootFolder)

	runeSets := [][]rune{
		[]rune(strings.Emoji),
		strings.AllRunes(unicode.Katakana),
		strings.AllRunes(unicode.Khmer),
		strings.AllRunes(unicode.Nl),
		strings.AllRunes(unicode.Lo),
		strings.AllRunes(unicode.Sc),
		strings.AllRunes(unicode.Greek),
		strings.AllRunes(unicode.Other_Grapheme_Extend),
		strings.AllRunes(unicode.Avestan),
	}

	formatSet := []formats.Format{
		formats.Folder{},
		formats.Text{},
	}

	for _, runes := range runeSets {
		for _, format := range formatSet {
			replacer.Add(format, strings.NewRandomPicker(10, runes))
		}
	}

	done := make(chan bool)

	c := make(chan notify.EventInfo, 1000)
	if err := notify.Watch(rootFolder, c, notify.Rename, notify.Remove); err != nil {
		log.Fatal(err)
	}
	defer notify.Stop(c)
	go func() {
		for {
			select {
			case event := <-c:
				replacer.Replace(event.Path())
			}
		}
	}()

	<-done
}
<commit_msg>Added naughty strings<commit_after>package main

import (
	"log"
	"unicode"

	"github.com/rjeczalik/notify"

	"bigoh.co.uk/language-tool/formats"
	"bigoh.co.uk/language-tool/replacer"
	"bigoh.co.uk/language-tool/strings"
)

func main() {
	rootFolder := "/Users/neilmoore67/tmp/foo"

	replacer := replacer.NewMakerRegistry(rootFolder)

	runeSets := [][]rune{
		[]rune(strings.Emoji),
		strings.AllRunes(unicode.Katakana),
		strings.AllRunes(unicode.Khmer),
		strings.AllRunes(unicode.Nl),
		strings.AllRunes(unicode.Lo),
		strings.AllRunes(unicode.Sc),
		strings.AllRunes(unicode.Greek),
		strings.AllRunes(unicode.Other_Grapheme_Extend),
		strings.AllRunes(unicode.Avestan),
	}

	formatSet := []formats.Format{
		formats.Folder{},
		formats.Text{},
	}

	for _, format := range formatSet {
		replacer.Add(format, strings.NewNaughty())
		for _, runes := range runeSets {
			replacer.Add(format, strings.NewRandomPicker(10, runes))
		}
	}

	done := make(chan bool)

	c := make(chan notify.EventInfo, 1000)
	if err := notify.Watch(rootFolder, c, notify.Rename, notify.Remove); err != nil {
		log.Fatal(err)
	}
	defer notify.Stop(c)
	go func() {
		for {
			select {
			case event := <-c:
				replacer.Replace(event.Path())
			}
		}
	}()

	<-done
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"runtime"

	"github.com/go-gl/gl/v4.1-core/gl"
	"github.com/go-gl/glfw/v3.1/glfw"
)

const windowWidth = 800
const windowHeight = 600

func init() {
	// GLFW event handling must run on the main OS thread
	runtime.LockOSThread()
	log.Print("OS thread locked")
}

func main() {
	if err := glfw.Init(); err != nil {
		log.Fatalln("failed to initialize glfw:", err)
	}
	defer glfw.Terminate()

	glfw.WindowHint(glfw.Resizable, glfw.False)
	glfw.WindowHint(glfw.ContextVersionMajor, 4)
	glfw.WindowHint(glfw.ContextVersionMinor, 1)
	glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile)
	glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True)
	window, err := glfw.CreateWindow(windowWidth, windowHeight, "Frame Assault", nil, nil)
	if err != nil {
		panic(err)
	}
	window.MakeContextCurrent()

	// Initialize Glow
	if err := gl.Init(); err != nil {
		panic(err)
	}

	version := gl.GoStr(gl.GetString(gl.VERSION))
	fmt.Println("OpenGL version", version)

	for !window.ShouldClose() {
		gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)

		//Update

		//Render

		// Maintenance
		window.SwapBuffers()
		glfw.PollEvents()
	}

}
<commit_msg>Initial gl settings.<commit_after>package main

import (
	"fmt"
	"log"
	"runtime"

	"github.com/go-gl/gl/v4.1-core/gl"
	"github.com/go-gl/glfw/v3.1/glfw"
)

const windowWidth = 800
const windowHeight = 600

func init() {
	// GLFW event handling must run on the main OS thread
	runtime.LockOSThread()
	log.Print("OS thread locked")
}

func main() {
	if err := glfw.Init(); err != nil {
		log.Fatalln("failed to initialize glfw:", err)
	}
	defer glfw.Terminate()

	glfw.WindowHint(glfw.Resizable, glfw.False)
	glfw.WindowHint(glfw.ContextVersionMajor, 4)
	glfw.WindowHint(glfw.ContextVersionMinor, 1)
	glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile)
	glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True)
	window, err := glfw.CreateWindow(windowWidth, windowHeight, "Frame Assault", nil, nil)
	if err != nil {
		panic(err)
	}
	window.MakeContextCurrent()

	// Initialize Glow
	if err := gl.Init(); err != nil {
		panic(err)
	}

	version := gl.GoStr(gl.GetString(gl.VERSION))
	fmt.Println("OpenGL version", version)

	// Configure global settings
	gl.Enable(gl.DEPTH_TEST)
	gl.DepthFunc(gl.LESS)
	gl.ClearColor(1.0, 1.0, 1.0, 1.0)

	for !window.ShouldClose() {
		gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)

		//Update

		//Render

		// Maintenance
		window.SwapBuffers()
		glfw.PollEvents()
	}

}
<|endoftext|>


<commit_before>// Copyright 2011 Google Inc. All Rights Reserved.
// This file is available under the Apache license.

package main

import (
	"encoding/csv"
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strings"

	_ "net/http/pprof"
)

var port *string = flag.String("port", "3903", "HTTP port to listen on.")
var logs *string = flag.String("logs", "", "List of files to monitor.")
var progs *string = flag.String("progs", "", "Directory containing programs")

// Global metrics storage.
var metrics []*Metric

// CSV export
func handleCsv(w http.ResponseWriter, r *http.Request) {
	c := csv.NewWriter(w)
	for _, m := range metrics {
		record := []string{m.Name,
			fmt.Sprintf("%f", m.Value),
			fmt.Sprintf("%s", m.Time),
			fmt.Sprintf("%d", m.Type),
			m.Unit}
		for k, v := range m.Tags {
			record = append(record, fmt.Sprintf("%s=%s", k, v))
		}
		c.Write(record)
	}
	c.Flush()
}

type Foo struct {
	Name string
}

// JSON export
func handleJson(w http.ResponseWriter, r *http.Request) {
	b, err := json.Marshal(metrics)
	if err != nil {
		log.Println("error marshalling metrics into json:", err.Error())
	}
	w.Write(b)
}

// vms contains a list of virtual machines to execute when each new line is received
var vms []*vm

// RunVms receives a line from a channel and sends it to all VMs.
func RunVms(lines chan string) {
	for {
		select {
		case line := <-lines:
			for _, v := range vms {
				v.Run(line)
			}
		}
	}

}

func main() {
	flag.Parse()
	w := NewWatcher()
	t := NewTailer(w)

	fis, err := ioutil.ReadDir(*progs)
	if err != nil {
		log.Fatalf("Failure reading progs from %q: %s", *progs, err)
	}
	for _, fi := range fis {
		f, err := os.Open(fmt.Sprintf("%s/%s", *progs, fi.Name()))
		if err != nil {
			log.Printf("Failed to open %s: %s\n", fi.Name(), err)
			continue
		}
		defer f.Close()
		vm, errors := Compile(fi.Name(), f)
		if errors != nil {
			for _, e := range errors {
				log.Printf(e)
			}
			continue
		}
		vms = append(vms, vm)
	}

	go RunVms(t.Line)
	go t.start()
	go w.start()

	for _, pathname := range strings.Split(*logs, ",") {
		t.Tail(pathname)
	}

	http.HandleFunc("/json", handleJson)
	http.HandleFunc("/csv", handleCsv)
	log.Fatal(http.ListenAndServe(":"+*port, nil))

}
<commit_msg>Don't try to compile directories.<commit_after>// Copyright 2011 Google Inc. All Rights Reserved.
// This file is available under the Apache license.

package main

import (
	"encoding/csv"
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strings"

	_ "net/http/pprof"
)

var port *string = flag.String("port", "3903", "HTTP port to listen on.")
var logs *string = flag.String("logs", "", "List of files to monitor.")
var progs *string = flag.String("progs", "", "Directory containing programs")

// Global metrics storage.
var metrics []*Metric

// CSV export
func handleCsv(w http.ResponseWriter, r *http.Request) {
	c := csv.NewWriter(w)
	for _, m := range metrics {
		record := []string{m.Name,
			fmt.Sprintf("%f", m.Value),
			fmt.Sprintf("%s", m.Time),
			fmt.Sprintf("%d", m.Type),
			m.Unit}
		for k, v := range m.Tags {
			record = append(record, fmt.Sprintf("%s=%s", k, v))
		}
		c.Write(record)
	}
	c.Flush()
}

type Foo struct {
	Name string
}

// JSON export
func handleJson(w http.ResponseWriter, r *http.Request) {
	b, err := json.Marshal(metrics)
	if err != nil {
		log.Println("error marshalling metrics into json:", err.Error())
	}
	w.Write(b)
}

// vms contains a list of virtual machines to execute when each new line is received
var vms []*vm

// RunVms receives a line from a channel and sends it to all VMs.
func RunVms(lines chan string) {
	for {
		select {
		case line := <-lines:
			for _, v := range vms {
				v.Run(line)
			}
		}
	}

}

func main() {
	flag.Parse()
	w := NewWatcher()
	t := NewTailer(w)

	fis, err := ioutil.ReadDir(*progs)
	if err != nil {
		log.Fatalf("Failure reading progs from %q: %s", *progs, err)
	}
	for _, fi := range fis {
		if fi.IsDir() {
			continue
		}
		f, err := os.Open(fmt.Sprintf("%s/%s", *progs, fi.Name()))
		if err != nil {
			log.Printf("Failed to open %s: %s\n", fi.Name(), err)
			continue
		}
		defer f.Close()
		vm, errors := Compile(fi.Name(), f)
		if errors != nil {
			for _, e := range errors {
				log.Printf(e)
			}
			continue
		}
		vms = append(vms, vm)
	}

	go RunVms(t.Line)
	go t.start()
	go w.start()

	for _, pathname := range strings.Split(*logs, ",") {
		t.Tail(pathname)
	}

	http.HandleFunc("/json", handleJson)
	http.HandleFunc("/csv", handleCsv)
	log.Fatal(http.ListenAndServe(":"+*port, nil))

}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strings"

	"github.com/BurntSushi/toml"
	"github.com/mitchellh/go-homedir"
)

var minecraftPath string

func init() {
	homePath, err := homedir.Dir()
	if err != nil {
		panic(err)
	}
	minecraftPath = filepath.Join(homePath, ".minecraft")
}

func usage() {
	os.Stderr.WriteString(`
Usage: mcm [OPTION]... RECIPE

Options:
	--help       show this help message
	--version    print the version
`[1:])
}

func version() {
	os.Stderr.WriteString(`
mcm: v0.4.0
`[1:])
}

func exists(path string) bool {
	_, err := os.Stat(path)
	return err == nil
}

type Profile struct {
	Profiles map[string]struct {
		GameDir       string
		LastVersionId string
	}
}

func (p *Profile) Valid(name string) bool {
	_, ok := p.Profiles[name]
	return ok
}

type Package struct {
	Name string `toml:"name"`
	URL  string `toml:"url"`
}

type Manager struct {
	log           *log.Logger
	prof          *Profile
	errors        []string
	root          string
	Name          string    `toml:"name"`
	Mods          []Package `toml:"mod"`
	ResourcePacks []Package `toml:"resourcepack"`
}

func NewManager(w io.Writer) *Manager {
	return &Manager{
		log: log.New(w, "", log.LstdFlags),
	}
}

func (m *Manager) InfoLog(a ...string) {
	m.log.Println("INFO:", strings.Join(a, " "))
}

func (m *Manager) ErrorLog(err error, a ...string) {
	m.log.Println("ERRO:", strings.Join(a, " "))
	m.errors = append(m.errors, err.Error())
}

func (m *Manager) FatalLog(a ...string) {
	m.log.Println("FATA:", strings.Join(a, " "))
}

func (m *Manager) LoadProfile() error {
	path := filepath.Join(minecraftPath, "launcher_profiles.json")

	m.InfoLog("Load profile:", path)
	f, err := os.Open(path)
	if err != nil {
		m.FatalLog("Failed open profile:", path)
		return err
	}
	defer f.Close()

	m.prof = &Profile{}
	if err = json.NewDecoder(f).Decode(m.prof); err != nil {
		m.FatalLog("Failed read profile:", path)
		return err
	}
	return nil
}

func (m *Manager) LoadRecipe(path string) error {
	m.InfoLog("Load recipe:", path)
	_, err := toml.DecodeFile(path, m)
	if err != nil {
		m.FatalLog("Failed load recipe")
		return err
	}

	if m.Name != "" && !m.prof.Valid(m.Name) {
		m.FatalLog("Failed find the version name:", m.Name)
		return fmt.Errorf("invalid version name: %s", m.Name)
	}
	if m.Name == "" || m.prof.Profiles[m.Name].GameDir == "" {
		m.root = minecraftPath
		return nil
	}
	m.root = m.prof.Profiles[m.Name].GameDir
	return nil
}

func (m *Manager) Download(kind string, a []Package) error {
	rootPath := filepath.Join(m.root, kind)

	m.InfoLog("Start install "+kind+" to:", rootPath)
	if !exists(rootPath) {
		m.InfoLog("Create "+kind+" directory")
		if err := os.MkdirAll(rootPath, 0755); err != nil {
			m.FatalLog("Failed create "+kind+" directory")
			return err
		}
	}

	for _, p := range a {
		path := filepath.Join(rootPath, p.Name)
		if exists(path) {
			m.InfoLog("Already installed:", p.Name)
			continue
		}

		m.InfoLog("Start install:", p.Name)
		f, err := os.Create(path)
		if err != nil {
			m.ErrorLog(err, "Failed create file:", path)
			continue
		}

		m.InfoLog("Download from:", p.URL)
		res, err := http.Get(p.URL)
		if err != nil {
			m.ErrorLog(err, "Failed download:", p.URL)
			continue
		}
		defer res.Body.Close()

		m.InfoLog("Install to:", path)
		_, err = io.Copy(f, res.Body)
		if err != nil {
			m.ErrorLog(err, "Failed write to:", path)
			continue
		}
	}
	return nil
}

func (m *Manager) Execute(recipePath string) error {
	m.InfoLog("Start mcm")
	if err := m.LoadProfile(); err != nil {
		return err
	}
	if err := m.LoadRecipe(recipePath); err != nil {
		return err
	}
	if err := m.Download("mods", m.Mods); err != nil {
		return err
	}
	if err := m.Download("resourcepacks", m.ResourcePacks); err != nil {
		return err
	}

	if len(m.errors) > 0 {
		return fmt.Errorf("%d errors occurred:\n%s",
			len(m.errors), strings.Join(m.errors, "\n"))
	}
	return nil
}

func main() {
	isHelp := flag.Bool("help", false, "")
	isVersion := flag.Bool("version", false, "")
	flag.Usage = usage
	flag.Parse()

	if *isHelp {
		usage()
		os.Exit(2)
	}
	if *isVersion {
		version()
		os.Exit(2)
	}
	if flag.NArg() < 1 {
		fmt.Fprintln(os.Stderr, "mcm:", "no input file")
		usage()
		os.Exit(1)
	}
	recipe := flag.Arg(0)

	m := NewManager(os.Stdout)
	if err := m.Execute(recipe); err != nil {
		fmt.Fprintln(os.Stderr, "mcm:", err)
		os.Exit(1)
	}
}
<commit_msg>To show fullpath of recipe file in log<commit_after>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strings"

	"github.com/BurntSushi/toml"
	"github.com/mitchellh/go-homedir"
)

var minecraftPath string

func init() {
	homePath, err := homedir.Dir()
	if err != nil {
		panic(err)
	}
	minecraftPath = filepath.Join(homePath, ".minecraft")
}

func usage() {
	os.Stderr.WriteString(`
Usage: mcm [OPTION]... RECIPE

Options:
	--help       show this help message
	--version    print the version
`[1:])
}

func version() {
	os.Stderr.WriteString(`
mcm: v0.4.0
`[1:])
}

func exists(path string) bool {
	_, err := os.Stat(path)
	return err == nil
}

type Profile struct {
	Profiles map[string]struct {
		GameDir       string
		LastVersionId string
	}
}

func (p *Profile) Valid(name string) bool {
	_, ok := p.Profiles[name]
	return ok
}

type Package struct {
	Name string `toml:"name"`
	URL  string `toml:"url"`
}

type Manager struct {
	log           *log.Logger
	prof          *Profile
	errors        []string
	root          string
	Name          string    `toml:"name"`
	Mods          []Package `toml:"mod"`
	ResourcePacks []Package `toml:"resourcepack"`
}

func NewManager(w io.Writer) *Manager {
	return &Manager{
		log: log.New(w, "", log.LstdFlags),
	}
}

func (m *Manager) InfoLog(a ...string) {
	m.log.Println("INFO:", strings.Join(a, " "))
}

func (m *Manager) ErrorLog(err error, a ...string) {
	m.log.Println("ERRO:", strings.Join(a, " "))
	m.errors = append(m.errors, err.Error())
}

func (m *Manager) FatalLog(a ...string) {
	m.log.Println("FATA:", strings.Join(a, " "))
}

func (m *Manager) LoadProfile() error {
	path := filepath.Join(minecraftPath, "launcher_profiles.json")

	m.InfoLog("Load profile:", path)
	f, err := os.Open(path)
	if err != nil {
		m.FatalLog("Failed open profile:", path)
		return err
	}
	defer f.Close()

	m.prof = &Profile{}
	if err = json.NewDecoder(f).Decode(m.prof); err != nil {
		m.FatalLog("Failed read profile:", path)
		return err
	}
	return nil
}

func (m *Manager) LoadRecipe(path string) error {
	fullPath, err := filepath.Abs(path)
	if err != nil {
		m.FatalLog("Invalid path:", err.Error())
	}

	m.InfoLog("Load recipe:", fullPath)
	_, err = toml.DecodeFile(fullPath, m)
	if err != nil {
		m.FatalLog("Failed load recipe")
		return err
	}

	if m.Name != "" && !m.prof.Valid(m.Name) {
		m.FatalLog("Failed find the version name:", m.Name)
		return fmt.Errorf("invalid version name: %s", m.Name)
	}
	if m.Name == "" || m.prof.Profiles[m.Name].GameDir == "" {
		m.root = minecraftPath
		return nil
	}
	m.root = m.prof.Profiles[m.Name].GameDir
	return nil
}

func (m *Manager) Download(kind string, a []Package) error {
	rootPath := filepath.Join(m.root, kind)

	m.InfoLog("Start install "+kind+" to:", rootPath)
	if !exists(rootPath) {
		m.InfoLog("Create "+kind+" directory")
		if err := os.MkdirAll(rootPath, 0755); err != nil {
			m.FatalLog("Failed create "+kind+" directory")
			return err
		}
	}

	for _, p := range a {
		path := filepath.Join(rootPath, p.Name)
		if exists(path) {
			m.InfoLog("Already installed:", p.Name)
			continue
		}

		m.InfoLog("Start install:", p.Name)
		f, err := os.Create(path)
		if err != nil {
			m.ErrorLog(err, "Failed create file:", path)
			continue
		}

		m.InfoLog("Download from:", p.URL)
		res, err := http.Get(p.URL)
		if err != nil {
			m.ErrorLog(err, "Failed download:", p.URL)
			continue
		}
		defer res.Body.Close()

		m.InfoLog("Install to:", path)
		_, err = io.Copy(f, res.Body)
		if err != nil {
			m.ErrorLog(err, "Failed write to:", path)
			continue
		}
	}
	return nil
}

func (m *Manager) Execute(recipePath string) error {
	m.InfoLog("Start mcm")
	if err := m.LoadProfile(); err != nil {
		return err
	}
	if err := m.LoadRecipe(recipePath); err != nil {
		return err
	}
	if err := m.Download("mods", m.Mods); err != nil {
		return err
	}
	if err := m.Download("resourcepacks", m.ResourcePacks); err != nil {
		return err
	}

	if len(m.errors) > 0 {
		return fmt.Errorf("%d errors occurred:\n%s",
			len(m.errors), strings.Join(m.errors, "\n"))
	}
	return nil
}

func main() {
	isHelp := flag.Bool("help", false, "")
	isVersion := flag.Bool("version", false, "")
	flag.Usage = usage
	flag.Parse()

	if *isHelp {
		usage()
		os.Exit(2)
	}
	if *isVersion {
		version()
		os.Exit(2)
	}
	if flag.NArg() < 1 {
		fmt.Fprintln(os.Stderr, "mcm:", "no input file")
		usage()
		os.Exit(1)
	}
	recipe := flag.Arg(0)

	m := NewManager(os.Stdout)
	if err := m.Execute(recipe); err != nil {
		fmt.Fprintln(os.Stderr, "mcm:", err)
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>package main

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

	"github.com/mundipagg/boleto-api/app"
	"github.com/mundipagg/boleto-api/config"
	"github.com/mundipagg/boleto-api/log"
)

var (
	env          string
	processID    = os.Getpid()
	devMode      = flag.Bool("dev", false, "-dev To run in dev mode")
	mockMode     = flag.Bool("mock", false, "-mock To run mock requests")
	disableLog   = flag.Bool("nolog", false, "-nolog disable seq log")
	airPlaneMode = flag.Bool("airplane-mode", false, "-airplane-mode run api in dev, mock and nolog mode")
	mockOnly     = flag.Bool("mockonly", false, "-mockonly run just mock service")
)

func init() {
	createPIDfile()
	// Configure signal handler
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	signal.Notify(c, syscall.SIGTERM)
	go handleSignal(c)
}

func handleSignal(c chan os.Signal) {
	<-c
	config.Stop()
	log.Info("Quiting BoletoApi")
	log.Close()

	fmt.Println("Done")
	os.Exit(1)
}

func createPIDfile() {
	p := strconv.Itoa(processID)
	ioutil.WriteFile("boletoapi.pid", []byte(p), 0644)
}

func main() {
	flag.Parse()
	runtime.GOMAXPROCS(runtime.NumCPU())
	if *mockOnly {
		w := make(chan int)
		config.Install(true, true, true)
		// robot.GoRobots()
		<-w
	} else {
		params := app.NewParams()
		if *airPlaneMode {
			params.DevMode = true
			params.DisableLog = false
			params.MockMode = true
			env = strconv.FormatBool(params.DevMode)
		} else {
			params.DevMode = *devMode
			params.DisableLog = *disableLog
			params.MockMode = *mockMode
			env = strconv.FormatBool(params.DevMode)
		}

		logo(env)
		app.Run(params)
	}

}

func logo(env string) {
	l := `
$$$$$$$\            $$\            $$\                $$$$$$\            $$\
$$  __$$\           $$ |           $$ |              $$  __$$\           \__|
$$ |  $$ | $$$$$$\  $$ | $$$$$$\ $$$$$$\    $$$$$$\  $$ /  $$ | $$$$$$\  $$\
$$$$$$$\ |$$  __$$\ $$ |$$  __$$\\_$$  _|  $$  __$$\ $$$$$$$$ |$$  __$$\ $$ |
$$  __$$\ $$ /  $$ |$$ |$$$$$$$$ | $$ |    $$ /  $$ |$$  __$$ |$$ /  $$ |$$ |
$$ |  $$ |$$ |  $$ |$$ |$$   ____| $$ |$$\ $$ |  $$ |$$ |  $$ |$$ |  $$ |$$ |
$$$$$$$  |\$$$$$$  |$$ |\$$$$$$$\  \$$$$  |\$$$$$$  |$$ |  $$ |$$$$$$$  |$$ |
\_______/  \______/ \__| \_______|  \____/  \______/ \__|  \__|$$  ____/ \__|
                                                               $$ |
                                                               $$ |
                                                               \__|
	`
	fmt.Println(l)
	fmt.Println("Version: " + config.Get().Version)
	fmt.Println("DevMode: " + env)
	fmt.Println("RecoveryRobot Enabled: " + config.Get().RecoveryRobotExecutionEnabled)
}
<commit_msg>:construction: Testando copy de certificados<commit_after>package main

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

	"github.com/mundipagg/boleto-api/app"
	"github.com/mundipagg/boleto-api/config"
	"github.com/mundipagg/boleto-api/log"
)

var (
	env          string
	processID    = os.Getpid()
	devMode      = flag.Bool("dev", false, "-dev To run in dev mode")
	mockMode     = flag.Bool("mock", false, "-mock To run mock requests")
	disableLog   = flag.Bool("nolog", false, "-nolog disable seq log")
	airPlaneMode = flag.Bool("airplane-mode", false, "-airplane-mode run api in dev, mock and nolog mode")
	mockOnly     = flag.Bool("mockonly", false, "-mockonly run just mock service")
)

func init() {
	createPIDfile()
	// Configure signal handler
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	signal.Notify(c, syscall.SIGTERM)
	go handleSignal(c)
}

func handleSignal(c chan os.Signal) {
	<-c
	config.Stop()
	log.Info("Quiting BoletoApi")
	log.Close()

	fmt.Println("Done")
	os.Exit(1)
}

func createPIDfile() {
	p := strconv.Itoa(processID)
	ioutil.WriteFile("boletoapi.pid", []byte(p), 0644)
}

func main() {
	flag.Parse()
	runtime.GOMAXPROCS(runtime.NumCPU())
	if *mockOnly {
		w := make(chan int)
		config.Install(true, true, true)
		// robot.GoRobots()
		<-w
	} else {
		params := app.NewParams()
		if *airPlaneMode {
			params.DevMode = true
			params.DisableLog = false
			params.MockMode = true
			env = strconv.FormatBool(params.DevMode)
		} else {
			params.DevMode = *devMode
			params.DisableLog = *disableLog
			params.MockMode = *mockMode
			env = strconv.FormatBool(params.DevMode)

			execPath, _ := os.Getwd()
			ftest := strings.Split(config.Get().CertBoletoPathCa, "/")
			fileName := ftest[len(ftest)-1]
			srcFile, err := os.Open(execPath + "/boleto_orig/" + fileName)
			if err != nil {
				fmt.Println("Error : %s", err.Error())
				os.Exit(1)
			}
			defer srcFile.Close()

			destFile, err := os.Create(execPath + "/boleto_cert/" + fileName)
			if err != nil {
				fmt.Println("Error : %s", err.Error())
				os.Exit(1)
			}
			defer destFile.Close()

			_, err = io.Copy(destFile, srcFile)
			if err != nil {
				fmt.Println("Error : %s", err.Error())
				os.Exit(1)
			}

			err = destFile.Sync()
			if err != nil {
				fmt.Println("Error : %s", err.Error())
				os.Exit(1)
			}

		}

		logo(env)
		app.Run(params)
	}

}

func logo(env string) {
	l := `
$$$$$$$\            $$\            $$\                $$$$$$\            $$\
$$  __$$\           $$ |           $$ |              $$  __$$\           \__|
$$ |  $$ | $$$$$$\  $$ | $$$$$$\ $$$$$$\    $$$$$$\  $$ /  $$ | $$$$$$\  $$\
$$$$$$$\ |$$  __$$\ $$ |$$  __$$\\_$$  _|  $$  __$$\ $$$$$$$$ |$$  __$$\ $$ |
$$  __$$\ $$ /  $$ |$$ |$$$$$$$$ | $$ |    $$ /  $$ |$$  __$$ |$$ /  $$ |$$ |
$$ |  $$ |$$ |  $$ |$$ |$$   ____| $$ |$$\ $$ |  $$ |$$ |  $$ |$$ |  $$ |$$ |
$$$$$$$  |\$$$$$$  |$$ |\$$$$$$$\  \$$$$  |\$$$$$$  |$$ |  $$ |$$$$$$$  |$$ |
\_______/  \______/ \__| \_______|  \____/  \______/ \__|  \__|$$  ____/ \__|
                                                               $$ |
                                                               $$ |
                                                               \__|
	`
	fmt.Println(l)
	fmt.Println("Version: " + config.Get().Version)
	fmt.Println("DevMode: " + env)
	fmt.Println("RecoveryRobot Enabled: " + config.Get().RecoveryRobotExecutionEnabled)
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"
)

func shortUsage() {
	os.Stderr.WriteString(`
Usage: vub [OPTION]... URI
Try 'vub --help' for more information.
`[1:])
}

func usage() {
	os.Stderr.WriteString(`
Usage: vub [OPTION]... URI
Install Vim plugin to under the management of vim-unbundle.

URI:
  sunaku/vim-unbundle                    # short URI
  https://github.com/sunaku/vim-unbundle # full URI

Options:
  -f, --filetype=TYPE       installing under the ftbundle/TYPE
  -r, --remove              change the behavior to remove
  -u, --update              change the behavior to clean update
  -v, --verbose             display the process
  -h, --help                show this help message
`[1:])
}

func main() {
	var filetype string
	flag.StringVar(&filetype, "f", "", "")
	flag.StringVar(&filetype, "filetype", "", "")

	var removeMode, updateMode bool
	flag.BoolVar(&removeMode, "r", false, "")
	flag.BoolVar(&removeMode, "remove", false, "")
	flag.BoolVar(&updateMode, "u", false, "")
	flag.BoolVar(&updateMode, "update", false, "")

	var verbose bool
	flag.BoolVar(&verbose, "v", false, "")
	flag.BoolVar(&verbose, "verbose", false, "")

	var isHelp bool
	flag.BoolVar(&isHelp, "h", false, "")
	flag.BoolVar(&isHelp, "help", false, "")
	flag.Usage = usage
	flag.Parse()
	switch {
	case isHelp:
		usage()
		os.Exit(0)
	case flag.NArg() < 1:
		shortUsage()
		os.Exit(2)
	case removeMode && updateMode:
		fmt.Fprintln(os.Stderr, "vub:", "cannot specify multiple mode")
		shortUsage()
		os.Exit(2)
	}
	uri := flag.Arg(0)

	p, err := NewPackage(uri, filetype)
	if err != nil {
		fmt.Fprintln(os.Stderr, "vub:", err)
		os.Exit(2)
	}
	p.Verbose(verbose)

	switch {
	case removeMode:
		if err := p.Remove(os.Stdout); err != nil {
			fmt.Fprintln(os.Stderr, "vub:", err)
			os.Exit(1)
		}
	case updateMode:
		if err := p.Update(os.Stdout); err != nil {
			fmt.Fprintln(os.Stderr, "vub:", err)
			os.Exit(1)
		}
	default:
		if err := p.Install(os.Stdout); err != nil {
			fmt.Fprintln(os.Stderr, "vub:", err)
			os.Exit(1)
		}
	}
}
<commit_msg>Summarize error handling at the top level<commit_after>package main

import (
	"flag"
	"fmt"
	"os"
)

func shortUsage() {
	os.Stderr.WriteString(`
Usage: vub [OPTION]... URI
Try 'vub --help' for more information.
`[1:])
}

func usage() {
	os.Stderr.WriteString(`
Usage: vub [OPTION]... URI
Install Vim plugin to under the management of vim-unbundle.

URI:
  sunaku/vim-unbundle                    # short URI
  https://github.com/sunaku/vim-unbundle # full URI

Options:
  -f, --filetype=TYPE       installing under the ftbundle/TYPE
  -r, --remove              change the behavior to remove
  -u, --update              change the behavior to clean update
  -v, --verbose             display the process
  -h, --help                show this help message
`[1:])
}

func _main() (code int, err error) {
	var filetype string
	flag.StringVar(&filetype, "f", "", "")
	flag.StringVar(&filetype, "filetype", "", "")

	var removeMode, updateMode bool
	flag.BoolVar(&removeMode, "r", false, "")
	flag.BoolVar(&removeMode, "remove", false, "")
	flag.BoolVar(&updateMode, "u", false, "")
	flag.BoolVar(&updateMode, "update", false, "")

	var verbose bool
	flag.BoolVar(&verbose, "v", false, "")
	flag.BoolVar(&verbose, "verbose", false, "")

	var isHelp bool
	flag.BoolVar(&isHelp, "h", false, "")
	flag.BoolVar(&isHelp, "help", false, "")
	flag.Usage = usage
	flag.Parse()
	switch {
	case isHelp:
		usage()
		return 0, nil
	case flag.NArg() < 1:
		return 2, nil
	case removeMode && updateMode:
		return 2, fmt.Errorf("cannot specify multiple mode")
	}
	uri := flag.Arg(0)

	p, err := NewPackage(uri, filetype)
	if err != nil {
		return 1, err
	}
	p.Verbose(verbose)

	switch {
	case removeMode:
		if err := p.Remove(os.Stdout); err != nil {
			return 1, err
		}
	case updateMode:
		if err := p.Update(os.Stdout); err != nil {
			return 1, err
		}
	default:
		if err := p.Install(os.Stdout); err != nil {
			return 1, err
		}
	}
	return 0, nil
}

func main() {
	code, err := _main()
	if err != nil {
		fmt.Fprintf(os.Stderr, "vub:", err)
	}
	if code == 2 {
		shortUsage()
	}
	os.Exit(code)
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/johto/notifyutils/notifydispatcher"
	"github.com/lib/pq"

	"fmt"
	"os"
	"sync"
	"time"
)

func printUsage() {
    fmt.Fprintf(os.Stderr, `Usage:
  %s [--help] configfile

Options:
  --help                display this help and exit
`, os.Args[0])
}

func main() {
	InitErrorLog(os.Stderr)

	if len(os.Args) != 2 {
		printUsage()
		os.Exit(1)
	} else if os.Args[1] == "--help" {
		printUsage()
		os.Exit(1)
	}

	err := readConfigFile(os.Args[1])
	if err != nil {
		elog.Fatalf("error while reading configuration file: %s", err)
	}
	if len(Config.Databases) == 0 {
		elog.Fatalf("at least one database must be configured")
	}

	l, err := Config.Listen.Listen()
	if err != nil {
		elog.Fatalf("could not open listen socket: %s", err)
	}

	var m sync.Mutex
	var connStatusNotifier chan struct{}

	listenerStateChange := func(ev pq.ListenerEventType, err error) {
		switch ev {
		case pq.ListenerEventConnectionAttemptFailed:
			elog.Warningf("Listener: could not connect to the database: %s", err.Error())

		case pq.ListenerEventDisconnected:
			elog.Warningf("Listener: lost connection to the database: %s", err.Error())
			m.Lock()
			close(connStatusNotifier)
			connStatusNotifier = nil
			m.Unlock()

		case pq.ListenerEventReconnected,
			pq.ListenerEventConnected:
			elog.Logf("Listener: connected to the database")
			m.Lock()
			connStatusNotifier = make(chan struct{})
			m.Unlock()
		}
	}

	// make sure pq.Listener doesn't pick up any env variables
	os.Clearenv()

	clientConnectionString := fmt.Sprintf("fallback_application_name=allas %s", Config.ClientConnInfo)
	listener := pq.NewListener(clientConnectionString,
		250*time.Millisecond, 15*time.Second,
		listenerStateChange)

	nd := notifydispatcher.NewNotifyDispatcher(listener)
	nd.SetBroadcastOnConnectionLoss(false)
	nd.SetSlowReaderEliminationStrategy(notifydispatcher.NeglectSlowReaders)

	for {
		c, err := l.Accept()
		if err != nil {
			panic(err)
		}

		Config.Listen.MaybeEnableKeepAlive(c)

		var myConnStatusNotifier chan struct{}

		m.Lock()
		if connStatusNotifier == nil {
			m.Unlock()
			go RejectFrontendConnection(c)
			continue
		} else {
			myConnStatusNotifier = connStatusNotifier
		}
		m.Unlock()

		newConn := NewFrontendConnection(c, nd, myConnStatusNotifier)
		go newConn.mainLoop(Config.StartupParameters, Config.Databases)
	}
}
<commit_msg>Try to connect even more often even if the server is unreachable for a while<commit_after>package main

import (
	"github.com/johto/notifyutils/notifydispatcher"
	"github.com/lib/pq"

	"fmt"
	"os"
	"sync"
	"time"
)

func printUsage() {
    fmt.Fprintf(os.Stderr, `Usage:
  %s [--help] configfile

Options:
  --help                display this help and exit
`, os.Args[0])
}

func main() {
	InitErrorLog(os.Stderr)

	if len(os.Args) != 2 {
		printUsage()
		os.Exit(1)
	} else if os.Args[1] == "--help" {
		printUsage()
		os.Exit(1)
	}

	err := readConfigFile(os.Args[1])
	if err != nil {
		elog.Fatalf("error while reading configuration file: %s", err)
	}
	if len(Config.Databases) == 0 {
		elog.Fatalf("at least one database must be configured")
	}

	l, err := Config.Listen.Listen()
	if err != nil {
		elog.Fatalf("could not open listen socket: %s", err)
	}

	var m sync.Mutex
	var connStatusNotifier chan struct{}

	listenerStateChange := func(ev pq.ListenerEventType, err error) {
		switch ev {
		case pq.ListenerEventConnectionAttemptFailed:
			elog.Warningf("Listener: could not connect to the database: %s", err.Error())

		case pq.ListenerEventDisconnected:
			elog.Warningf("Listener: lost connection to the database: %s", err.Error())
			m.Lock()
			close(connStatusNotifier)
			connStatusNotifier = nil
			m.Unlock()

		case pq.ListenerEventReconnected,
			pq.ListenerEventConnected:
			elog.Logf("Listener: connected to the database")
			m.Lock()
			connStatusNotifier = make(chan struct{})
			m.Unlock()
		}
	}

	// make sure pq.Listener doesn't pick up any env variables
	os.Clearenv()

	clientConnectionString := fmt.Sprintf("fallback_application_name=allas %s", Config.ClientConnInfo)
	listener := pq.NewListener(clientConnectionString,
		250*time.Millisecond, 3*time.Second,
		listenerStateChange)

	nd := notifydispatcher.NewNotifyDispatcher(listener)
	nd.SetBroadcastOnConnectionLoss(false)
	nd.SetSlowReaderEliminationStrategy(notifydispatcher.NeglectSlowReaders)

	for {
		c, err := l.Accept()
		if err != nil {
			panic(err)
		}

		Config.Listen.MaybeEnableKeepAlive(c)

		var myConnStatusNotifier chan struct{}

		m.Lock()
		if connStatusNotifier == nil {
			m.Unlock()
			go RejectFrontendConnection(c)
			continue
		} else {
			myConnStatusNotifier = connStatusNotifier
		}
		m.Unlock()

		newConn := NewFrontendConnection(c, nd, myConnStatusNotifier)
		go newConn.mainLoop(Config.StartupParameters, Config.Databases)
	}
}
<|endoftext|>


<commit_before>// Go Donut!
//
// originals:
// http://www.a1k0n.net/2011/07/20/donut-math.html  (original by Andy Sloane)
// https://github.com/GaryBoone/GoDonut             (donut.go by Gary Boone)
//
// This termbox version by Onno Siemens.
//
// Hint: hit enter while running. ESCape to quit.
//

package main

import (
	"github.com/nsf/termbox-go"
	"math"
	"time"
)

const frame_delay = 20
const theta_spacing = 0.02
const phi_spacing = 0.02

const R1 = 0.9
const R2 = 1.8
const K2 = 8.0

type Screen struct {
	dim        int
	lum24      [][]int
	data       [][]byte
	zoom       float64
	transition int
}

func newZBuffer(d int) *[][]float64 {
	b := make([][]float64, d)
	for i := range b {
		b[i] = make([]float64, d)
	}
	return &b
}

func newScreen(d int) *Screen {
	b := make([][]byte, d)
	c := make([][]int, d)
	for i := range b {
		b[i] = make([]byte, d)
		c[i] = make([]int, d)
	}
	a := float64(0)
	z := int(0)
	return &Screen{d, c, b, a, z}
}

func (screen *Screen) render(rendermode int) {
	switch rendermode {
	case 1:
		termbox.SetOutputMode(termbox.OutputGrayscale)
	case 2:
		termbox.SetOutputMode(termbox.Output216)
	case 3:
		termbox.SetOutputMode(termbox.Output216)
	default:
		termbox.SetOutputMode(termbox.OutputGrayscale)
	}
	for x, _ := range screen.data {
		for y, _ := range screen.data[x] {
			switch rendermode {
			case 1:
				screen.draw(x, y, ' ', screen.lum24[x][y], screen.lum24[x][y])
			case 2:
				screen.draw(x, y, rune(screen.data[x][y]), screen.lum24[x][y]/3+1, screen.lum24[x][y]/4)
			case 3:
				screen.draw(x, y, ' ', 0, screen.lum24[x][y])
			default:
				screen.draw(x, y, rune(screen.data[x][y]), screen.lum24[x][y], 0)
			}
		}
	}
	screen.clear()
}

func (screen *Screen) draw(x, y int, char rune, fg, bg int) {
	termbox.SetCell(x*2, y, char, termbox.Attribute(fg), termbox.Attribute(bg))
	termbox.SetCell(x*2-1, y, char, termbox.Attribute(fg), termbox.Attribute(bg))
}

func (screen *Screen) clear() {
	for x, _ := range screen.data {
		for y, _ := range screen.data[x] {
			if screen.lum24[x][y] == ' ' {
				screen.draw(x, y, ' ', 0, 0)
			} else {
				screen.data[x][y] = ' '
				screen.lum24[x][y] = ' '
			}
		}
	}
}

func (screen *Screen) computeFrame(A, B, K1 float64) {

	// precompute sines and cosines of A and B
	cosA := math.Cos(A)
	sinA := math.Sin(A)
	cosB := math.Cos(B)
	sinB := math.Sin(B)

	zbuffer := newZBuffer(screen.dim)

	// theta goes around the cross-sectional circle of a torus
	for theta := 0.0; theta < 2.0*math.Pi; theta += theta_spacing {
		// precompute sines and cosines of theta
		costheta := math.Cos(theta)
		sintheta := math.Sin(theta)

		// phi goes around the center of revolution of a torus
		for phi := 0.0; phi < 2.0*math.Pi; phi += phi_spacing {
			// precompute sines and cosines of phi
			cosphi := math.Cos(phi)
			sinphi := math.Sin(phi)

			// the x,y coordinate of the circle, before revolving (factored out of the above equations)
			circlex := R2 + R1*costheta
			circley := R1 * sintheta

			// final 3D (x,y,z) coordinate after rotations, directly from our math above
			x := circlex*(cosB*cosphi+sinA*sinB*sinphi) - circley*cosA*sinB
			y := circlex*(sinB*cosphi-sinA*cosB*sinphi) + circley*cosA*cosB
			z := K2 + cosA*circlex*sinphi + circley*sinA
			ooz := 1 / z // "one over z"

			// x and y projection.  note that y is negated here, because y goes up in
			// 3D space but down on 2D displays.
			xp := int(float64(screen.dim)/2.0 + K1*ooz*x)
			yp := int(float64(screen.dim)/2.0 - K1*ooz*y)

			// calculate luminance.  ugly, but correct.
			L := cosphi*costheta*sinB - cosA*costheta*sinphi - sinA*sintheta +
				cosB*(cosA*sintheta-costheta*sinA*sinphi)
			// L ranges from -sqrt(2) to +sqrt(2).  If it's < 0, the surface is
			// pointing away from us, so we won't bother trying to plot it.
			if L > 0 {
				// test against the z-buffer.  larger 1/z means the pixel is closer to
				// the viewer than what's already plotted.
				if ooz > (*zbuffer)[yp][xp] {
					(*zbuffer)[yp][xp] = ooz
					ascii_index := int(L * 8.0)  // this brings L into the range 0..11 (8*sqrt(2) = 11.3)
					lum24 := int((L * 16.0) + 1) // this brings L into the range 1..24 (16*sqrt(2) + 1 = 23.6)
					// now we lookup the character corresponding to the luminance and plot it in our output:
					screen.data[yp][xp] = ".,-~:;=!*#$@"[ascii_index]
					screen.lum24[yp][xp] = lum24
				}
			}
		}
	}
}

func main() {
	err := termbox.Init()
	if err != nil {
		panic(err)
	}
	defer termbox.Close()

	event_queue := make(chan termbox.Event)
	go func() {
		for {
			event_queue <- termbox.PollEvent()
		}
	}()
	w, h := termbox.Size()
	dim := int(math.Min(float64(w), float64(h)))
	screen := newScreen(dim)
	rendermode := int(0)
	termbox.SetOutputMode(termbox.OutputGrayscale)

	// Calculate K1 based on screen size: the maximum x-distance occurs roughly at
	// the edge of the torus, which is at x=R1+R2, z=0.  we want that to be
	// displaced 3/8ths of the width of the screen, which is 3/4th of the way from
	// the center to the side of the screen.
	//screen.dim*3/8 = K1*(R1+R2)/(K2+0)
	//screen.dim*K2*3/(8*(R1+R2)) = K1
	A, B, K1 := 1.0, 1.0, float64(screen.dim)*K2*3.0/(8.0*(R1+R2))

	// start zoomed out
	screen.zoom = K1
	K1 = 0
	screen.transition = 2

loop:
	for {
		select {
		case ev := <-event_queue:
			if ev.Type == termbox.EventKey && ev.Key == termbox.KeyEsc {
				break loop
			}
			if ev.Type == termbox.EventKey && ev.Key == termbox.KeyEnter {

				screen.transition = 1
			}

		default:
			// rotate the torus
			A += 0.07
			B += 0.03

			// zoom out if transitioning to new rendermode
			if screen.transition == 1 {
				K1 -= 2
			}
			// all the way zoomed out, switch rendermodes
			if K1 < 0 {
				screen.transition = 2
				rendermode++
				K1++
				if rendermode == 4 {
					rendermode = 0
				}
			}
			// zoom back in
			if screen.transition == 2 {
				if K1 < screen.zoom {
					K1 += 1.5
				}
				if K1 >= screen.zoom {
					K1 = screen.zoom
					screen.transition = 0
				}
			}
			// draw all the things
			screen.computeFrame(A, B, K1)
			screen.render(rendermode)
			termbox.Flush()
			time.Sleep(frame_delay * time.Millisecond)
		}
	}
}
<commit_msg>remove underscores from var names<commit_after>// Go Donut!
//
// originals:
// http://www.a1k0n.net/2011/07/20/donut-math.html  (original by Andy Sloane)
// https://github.com/GaryBoone/GoDonut             (donut.go by Gary Boone)
//
// This termbox version by Onno Siemens.
//
// Hint: hit enter while running. ESCape to quit.
//

package main

import (
	"github.com/nsf/termbox-go"
	"math"
	"time"
)

const framedelay = 20
const thetaspacing = 0.02
const phispacing = 0.02

const R1 = 0.9
const R2 = 1.8
const K2 = 8.0

type Screen struct {
	dim        int
	lum24      [][]int
	data       [][]byte
	zoom       float64
	transition int
}

func newZBuffer(d int) *[][]float64 {
	b := make([][]float64, d)
	for i := range b {
		b[i] = make([]float64, d)
	}
	return &b
}

func newScreen(d int) *Screen {
	b := make([][]byte, d)
	c := make([][]int, d)
	for i := range b {
		b[i] = make([]byte, d)
		c[i] = make([]int, d)
	}
	a := float64(0)
	z := int(0)
	return &Screen{d, c, b, a, z}
}

func (screen *Screen) render(rendermode int) {
	switch rendermode {
	case 1:
		termbox.SetOutputMode(termbox.OutputGrayscale)
	case 2:
		termbox.SetOutputMode(termbox.Output216)
	case 3:
		termbox.SetOutputMode(termbox.Output216)
	default:
		termbox.SetOutputMode(termbox.OutputGrayscale)
	}
	for x, _ := range screen.data {
		for y, _ := range screen.data[x] {
			switch rendermode {
			case 1:
				screen.draw(x, y, ' ', screen.lum24[x][y], screen.lum24[x][y])
			case 2:
				screen.draw(x, y, rune(screen.data[x][y]), screen.lum24[x][y]/3+1, screen.lum24[x][y]/4)
			case 3:
				screen.draw(x, y, ' ', 0, screen.lum24[x][y])
			default:
				screen.draw(x, y, rune(screen.data[x][y]), screen.lum24[x][y], 0)
			}
		}
	}
	screen.clear()
}

func (screen *Screen) draw(x, y int, char rune, fg, bg int) {
	termbox.SetCell(x*2, y, char, termbox.Attribute(fg), termbox.Attribute(bg))
	termbox.SetCell(x*2-1, y, char, termbox.Attribute(fg), termbox.Attribute(bg))
}

func (screen *Screen) clear() {
	for x, _ := range screen.data {
		for y, _ := range screen.data[x] {
			if screen.lum24[x][y] == ' ' {
				screen.draw(x, y, ' ', 0, 0)
			} else {
				screen.data[x][y] = ' '
				screen.lum24[x][y] = ' '
			}
		}
	}
}

func (screen *Screen) computeFrame(A, B, K1 float64) {

	// precompute sines and cosines of A and B
	cosA := math.Cos(A)
	sinA := math.Sin(A)
	cosB := math.Cos(B)
	sinB := math.Sin(B)

	zbuffer := newZBuffer(screen.dim)

	// theta goes around the cross-sectional circle of a torus
	for theta := 0.0; theta < 2.0*math.Pi; theta += thetaspacing {
		// precompute sines and cosines of theta
		costheta := math.Cos(theta)
		sintheta := math.Sin(theta)

		// phi goes around the center of revolution of a torus
		for phi := 0.0; phi < 2.0*math.Pi; phi += phispacing {
			// precompute sines and cosines of phi
			cosphi := math.Cos(phi)
			sinphi := math.Sin(phi)

			// the x,y coordinate of the circle, before revolving (factored out of the above equations)
			circlex := R2 + R1*costheta
			circley := R1 * sintheta

			// final 3D (x,y,z) coordinate after rotations, directly from our math above
			x := circlex*(cosB*cosphi+sinA*sinB*sinphi) - circley*cosA*sinB
			y := circlex*(sinB*cosphi-sinA*cosB*sinphi) + circley*cosA*cosB
			z := K2 + cosA*circlex*sinphi + circley*sinA
			ooz := 1 / z // "one over z"

			// x and y projection.  note that y is negated here, because y goes up in
			// 3D space but down on 2D displays.
			xp := int(float64(screen.dim)/2.0 + K1*ooz*x)
			yp := int(float64(screen.dim)/2.0 - K1*ooz*y)

			// calculate luminance.  ugly, but correct.
			L := cosphi*costheta*sinB - cosA*costheta*sinphi - sinA*sintheta +
				cosB*(cosA*sintheta-costheta*sinA*sinphi)
			// L ranges from -sqrt(2) to +sqrt(2).  If it's < 0, the surface is
			// pointing away from us, so we won't bother trying to plot it.
			if L > 0 {
				// test against the z-buffer.  larger 1/z means the pixel is closer to
				// the viewer than what's already plotted.
				if ooz > (*zbuffer)[yp][xp] {
					(*zbuffer)[yp][xp] = ooz
					asciiIndex := int(L * 8.0)  // this brings L into the range 0..11 (8*sqrt(2) = 11.3)
					lum24 := int((L * 16.0) + 1) // this brings L into the range 1..24 (16*sqrt(2) + 1 = 23.6)
					// now we lookup the character corresponding to the luminance and plot it in our output:
					screen.data[yp][xp] = ".,-~:;=!*#$@"[asciiIndex]
					screen.lum24[yp][xp] = lum24
				}
			}
		}
	}
}

func main() {
	err := termbox.Init()
	if err != nil {
		panic(err)
	}
	defer termbox.Close()

	eventQueue := make(chan termbox.Event)
	go func() {
		for {
			eventQueue <- termbox.PollEvent()
		}
	}()
	w, h := termbox.Size()
	dim := int(math.Min(float64(w), float64(h)))
	screen := newScreen(dim)
	rendermode := int(0)
	termbox.SetOutputMode(termbox.OutputGrayscale)

	// Calculate K1 based on screen size: the maximum x-distance occurs roughly at
	// the edge of the torus, which is at x=R1+R2, z=0.  we want that to be
	// displaced 3/8ths of the width of the screen, which is 3/4th of the way from
	// the center to the side of the screen.
	//screen.dim*3/8 = K1*(R1+R2)/(K2+0)
	//screen.dim*K2*3/(8*(R1+R2)) = K1
	A, B, K1 := 1.0, 1.0, float64(screen.dim)*K2*3.0/(8.0*(R1+R2))

	// start zoomed out
	screen.zoom = K1
	K1 = 0
	screen.transition = 2

loop:
	for {
		select {
		case ev := <-eventQueue:
			if ev.Type == termbox.EventKey && ev.Key == termbox.KeyEsc {
				break loop
			}
			if ev.Type == termbox.EventKey && ev.Key == termbox.KeyEnter {

				screen.transition = 1
			}

		default:
			// rotate the torus
			A += 0.07
			B += 0.03

			// zoom out if transitioning to new rendermode
			if screen.transition == 1 {
				K1 -= 2
			}
			// all the way zoomed out, switch rendermodes
			if K1 < 0 {
				screen.transition = 2
				rendermode++
				K1++
				if rendermode == 4 {
					rendermode = 0
				}
			}
			// zoom back in
			if screen.transition == 2 {
				if K1 < screen.zoom {
					K1 += 1.5
				}
				if K1 >= screen.zoom {
					K1 = screen.zoom
					screen.transition = 0
				}
			}
			// draw all the things
			screen.computeFrame(A, B, K1)
			screen.render(rendermode)
			termbox.Flush()
			time.Sleep(framedelay * time.Millisecond)
		}
	}
}
<|endoftext|>


<commit_before>package main

// This software is an expense tracker i made to read the transactions exported from
// my bank account.

import (
	"expensetracker/accounts"
	"expensetracker/categories"
	"expensetracker/infrastructure"
	"expensetracker/reports"
	"fmt"
	"log"

	flag "github.com/ogier/pflag"
)

// CommandCreateCategory handles category creation command
func CommandCreateCategory(name string) error {

	dbHandler := infrastructure.DatabaseHandler{}
	cr := categories.CategoryRepository{DBHandler: &dbHandler}
	i := categories.Interactor{Repository: &cr}
	_, err := i.NewCategory(name)
	if err != nil {
		// TODO: Handle error gracefully
		return err
	}

	return nil
}

// CommandShowReport handles report commands
func CommandShowReport(inputFilePath string) error {
	file, err := infrastructure.OpenFile(inputFilePath)
	if err != nil {
		return err
	}
	defer file.Close()

	err = reports.MonthlyReport(file)
	if err != nil {
		return err
	}

	return nil
}

func main() {

	var inputFilePath string
	flag.StringVarP(&inputFilePath, "load", "l", "", "Specify the path to the input file")

	var showReport bool
	flag.BoolVarP(&showReport, "report", "r", false, "Show report")

	var showBalance bool
	flag.BoolVarP(&showBalance, "balance", "b", false, "Show current balance")

	var createCategory string
	flag.StringVarP(&createCategory, "category", "c", "", "Create category")

	flag.Parse()

	if createCategory != "" {
		if err := CommandCreateCategory(createCategory); err != nil {
			log.Fatalf("Failed to create category: %s", err)
		}
	}

	if showReport {
		if err := CommandShowReport(inputFilePath); err != nil {
			log.Fatalf("Failed to show report %s", err)
		}
	}

	if showBalance {
		fmt.Println(accounts.CurrentBalance().String())
	}
}

// var DATABASE_NAME string = "./expensetracker.db"
// var DATABASE_ENGINE = "sqlite3"

// func toExcel(value decimal.Decimal, description string) {
// 	var file *xlsx.File
// 	var sheet *xlsx.Sheet
// 	var row *xlsx.Row
// 	var cell *xlsx.Cell
// 	var err error

// 	file = xlsx.NewFile()
// 	sheet, err = file.AddSheet("Sheet1")
// 	if err != nil {
// 		fmt.Printf(err.Error())
// 	}
// 	row = sheet.AddRow()
// 	cell = row.AddCell()
// 	cell.Value = description
// 	cell = row.AddCell()
// 	// cell.Value = strconv.FormatFloat(value, 'f', 2, 64)
// 	cell.Value = value.String()

// 	err = file.Save("MyXLSXFile.xlsx")
// 	if err != nil {
// 		fmt.Printf(err.Error())
// 	}
// }
<commit_msg>Removes TODO<commit_after>package main

// This software is an expense tracker i made to read the transactions exported from
// my bank account.

import (
	"expensetracker/accounts"
	"expensetracker/categories"
	"expensetracker/infrastructure"
	"expensetracker/reports"
	"fmt"
	"log"

	flag "github.com/ogier/pflag"
)

// CommandCreateCategory handles category creation command
func CommandCreateCategory(name string) error {

	dbHandler := infrastructure.DatabaseHandler{}
	cr := categories.CategoryRepository{DBHandler: &dbHandler}
	i := categories.Interactor{Repository: &cr}
	_, err := i.NewCategory(name)
	if err != nil {
		return err
	}

	return nil
}

// CommandShowReport handles report commands
func CommandShowReport(inputFilePath string) error {
	file, err := infrastructure.OpenFile(inputFilePath)
	if err != nil {
		return err
	}
	defer file.Close()

	err = reports.MonthlyReport(file)
	if err != nil {
		return err
	}

	return nil
}

func main() {

	var inputFilePath string
	flag.StringVarP(&inputFilePath, "load", "l", "", "Specify the path to the input file")

	var showReport bool
	flag.BoolVarP(&showReport, "report", "r", false, "Show report")

	var showBalance bool
	flag.BoolVarP(&showBalance, "balance", "b", false, "Show current balance")

	var createCategory string
	flag.StringVarP(&createCategory, "category", "c", "", "Create category")

	flag.Parse()

	if createCategory != "" {
		if err := CommandCreateCategory(createCategory); err != nil {
			log.Fatalf("Failed to create category: %s", err)
		}
	}

	if showReport {
		if err := CommandShowReport(inputFilePath); err != nil {
			log.Fatalf("Failed to show report %s", err)
		}
	}

	if showBalance {
		fmt.Println(accounts.CurrentBalance().String())
	}
}

// var DATABASE_NAME string = "./expensetracker.db"
// var DATABASE_ENGINE = "sqlite3"

// func toExcel(value decimal.Decimal, description string) {
// 	var file *xlsx.File
// 	var sheet *xlsx.Sheet
// 	var row *xlsx.Row
// 	var cell *xlsx.Cell
// 	var err error

// 	file = xlsx.NewFile()
// 	sheet, err = file.AddSheet("Sheet1")
// 	if err != nil {
// 		fmt.Printf(err.Error())
// 	}
// 	row = sheet.AddRow()
// 	cell = row.AddCell()
// 	cell.Value = description
// 	cell = row.AddCell()
// 	// cell.Value = strconv.FormatFloat(value, 'f', 2, 64)
// 	cell.Value = value.String()

// 	err = file.Save("MyXLSXFile.xlsx")
// 	if err != nil {
// 		fmt.Printf(err.Error())
// 	}
// }
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"flag"
	"fmt"
	"log"
	"net"
	"net/http"
	"regexp"
	"strconv"
	"time"
)

var debug *bool

const pattConn string = `^([a-z]{3,}):\/\/([^:]+):?([0-9]+)?$`

func logDebug(msg interface{}) {
	if *debug {
		log.Print(msg)
	}
}

// Connection data
type Connection struct {
	Type   string
	Scheme string
	Port   int
	Host   string
}

func buildConn(host string, port int, fullConn string) *Connection {
	if host != "" {
		return &Connection{Type: "tcp", Host: host, Port: port}
	}

	if fullConn == "" {
		return nil
	}

	res := regexp.MustCompile(pattConn).FindAllStringSubmatch(fullConn, -1)[0]
	if len(res) != 4 {
		return nil
	}

	port, err := strconv.Atoi(res[3])
	if err != nil {
		port = 80
	}

	conn := &Connection{Type: res[1], Host: res[2], Port: port}
	if conn.Type != "tcp" {
		conn.Scheme = conn.Type
		conn.Type = "tcp"
	}

	if conn.Scheme == "https" {
		conn.Port = 443
	}

	return conn
}

func pingTCP(conn *Connection, timeoutSeconds int) error {
	timeout := time.Duration(timeoutSeconds) * time.Second
	start := time.Now()
	address := fmt.Sprintf("%s:%d", conn.Host, conn.Port)
	logDebug("Dial adress: " + address)

	for {
		_, err := net.DialTimeout(conn.Type, address, time.Second)
		logDebug("ping TCP")

		if err == nil {
			logDebug("Up")
			return nil
		}

		logDebug("Down")
		logDebug(err)
		if time.Since(start) > timeout {
			return err
		}

		time.Sleep(500 * time.Millisecond)
	}
}

func pingHTTP(conn *Connection, timeoutSeconds int) error {
	timeout := time.Duration(timeoutSeconds) * time.Second
	start := time.Now()
	address := fmt.Sprintf("%s://%s:%d", conn.Scheme, conn.Host, conn.Port)
	logDebug("HTTP adress: " + address)

	for {
		resp, err := http.Get(address)
		logDebug("ping HTTP " + resp.Status)

		if err == nil && resp.StatusCode < http.StatusInternalServerError {
			return nil
		}

		if time.Since(start) > timeout {
			return errors.New(resp.Status)
		}

		time.Sleep(500 * time.Millisecond)
	}
}

func main() {
	fullConn := flag.String("full-connection", "", "full connection")
	host := flag.String("host", "", "host to connect")
	port := flag.Int("port", 80, "port to connect")
	timeout := flag.Int("timeout", 10, "time to wait until port become available")
	debug = flag.Bool("debug", false, "enable debug")

	flag.Parse()

	conn := buildConn(*host, *port, *fullConn)
	if conn == nil {
		log.Fatal("Invalid connection")
	}

	logDebug("Waiting " + strconv.Itoa(*timeout) + " seconds")
	if err := pingTCP(conn, *timeout); err != nil {
		log.Fatal(err)
	}

	if conn.Scheme != "http" && conn.Scheme != "https" {
		return
	}

	if err := pingHTTP(conn, *timeout); err != nil {
		log.Fatal(err)
	}
}
<commit_msg>Add support to print the current version<commit_after>package main

import (
	"errors"
	"flag"
	"fmt"
	"log"
	"net"
	"net/http"
	"regexp"
	"strconv"
	"time"
)

var debug *bool

const pattConn string = `^([a-z]{3,}):\/\/([^:]+):?([0-9]+)?$`

func logDebug(msg interface{}) {
	if *debug {
		log.Print(msg)
	}
}

// Connection data
type Connection struct {
	Type   string
	Scheme string
	Port   int
	Host   string
}

func buildConn(host string, port int, fullConn string) *Connection {
	if host != "" {
		return &Connection{Type: "tcp", Host: host, Port: port}
	}

	if fullConn == "" {
		return nil
	}

	res := regexp.MustCompile(pattConn).FindAllStringSubmatch(fullConn, -1)[0]
	if len(res) != 4 {
		return nil
	}

	port, err := strconv.Atoi(res[3])
	if err != nil {
		port = 80
	}

	conn := &Connection{Type: res[1], Host: res[2], Port: port}
	if conn.Type != "tcp" {
		conn.Scheme = conn.Type
		conn.Type = "tcp"
	}

	if conn.Scheme == "https" {
		conn.Port = 443
	}

	return conn
}

func pingTCP(conn *Connection, timeoutSeconds int) error {
	timeout := time.Duration(timeoutSeconds) * time.Second
	start := time.Now()
	address := fmt.Sprintf("%s:%d", conn.Host, conn.Port)
	logDebug("Dial adress: " + address)

	for {
		_, err := net.DialTimeout(conn.Type, address, time.Second)
		logDebug("ping TCP")

		if err == nil {
			logDebug("Up")
			return nil
		}

		logDebug("Down")
		logDebug(err)
		if time.Since(start) > timeout {
			return err
		}

		time.Sleep(500 * time.Millisecond)
	}
}

func pingHTTP(conn *Connection, timeoutSeconds int) error {
	timeout := time.Duration(timeoutSeconds) * time.Second
	start := time.Now()
	address := fmt.Sprintf("%s://%s:%d", conn.Scheme, conn.Host, conn.Port)
	logDebug("HTTP adress: " + address)

	for {
		resp, err := http.Get(address)
		logDebug("ping HTTP " + resp.Status)

		if err == nil && resp.StatusCode < http.StatusInternalServerError {
			return nil
		}

		if time.Since(start) > timeout {
			return errors.New(resp.Status)
		}

		time.Sleep(500 * time.Millisecond)
	}
}

func main() {
	fullConn := flag.String("full-connection", "", "full connection")
	host := flag.String("host", "", "host to connect")
	port := flag.Int("port", 80, "port to connect")
	timeout := flag.Int("timeout", 10, "time to wait until port become available")
	version := flag.Bool("v", false, "show the current version")
	debug = flag.Bool("debug", false, "enable debug")

	flag.Parse()

	if *version {
		fmt.Println("waitforit version 1.2.2")
		return
	}

	conn := buildConn(*host, *port, *fullConn)
	if conn == nil {
		log.Fatal("Invalid connection")
	}

	logDebug("Waiting " + strconv.Itoa(*timeout) + " seconds")
	if err := pingTCP(conn, *timeout); err != nil {
		log.Fatal(err)
	}

	if conn.Scheme != "http" && conn.Scheme != "https" {
		return
	}

	if err := pingHTTP(conn, *timeout); err != nil {
		log.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"os"

	"github.com/ogier/pflag"
	"github.com/yuya-takeyama/argf"
)

var (
	name    = "ltsvp"
	version = "0.5.0"

	flagset         = pflag.NewFlagSet(name, pflag.ContinueOnError)
	list            = flagset.StringP("keys", "k", "", "")
	outputDelimiter = flagset.StringP("output-delimiter", "D", "\t", "")
	remainLTSV      = flagset.BoolP("remain-ltsv", "r", false, "")
	isHelp          = flagset.BoolP("help", "h", false, "")
	isVersion       = flagset.BoolP("version", "v", false, "")
)

func printUsage() {
	fmt.Fprintf(os.Stderr, `
Usage: %s OPTION... [FILE]...
Print selected parts of LTSV from each FILE to standard output.

Options:
  -k, --keys=LIST
                 select only these keys (required)
  -D, --output-delimiter=STRING
                 use STRING to separate parts (default: \t)
  -r, --remain-ltsv
                 print selected parts as LTSV
  -h, --help
                 display this help text and exit
  -v, --version
                 output version information and exit

LIST is made up of keys separated by commas.
  host           # Select host
  host,time,ua   # Select host, time, and ua
`[1:], name)
}

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

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

func guideToHelp() {
	fmt.Fprintf(os.Stderr, "Try '%s --help' for more information.\n", name)
}

func do(l *LTSVScanner) error {
	for l.Scan() {
		fmt.Println(l.Text())
	}
	return l.Err()
}

func main() {
	flagset.SetOutput(ioutil.Discard)
	if err := flagset.Parse(os.Args[1:]); err != nil {
		printErr(err)
		guideToHelp()
		os.Exit(2)
	}
	switch {
	case *isHelp:
		printUsage()
		os.Exit(0)
	case *isVersion:
		printVersion()
		os.Exit(0)
	}

	specifiedList := false
	flagset.Visit(func(f *pflag.Flag) {
		if f.Name == "keys" {
			specifiedList = true
		}
	})
	if !specifiedList {
		printErr("no specify LIST")
		guideToHelp()
		os.Exit(2)
	}
	keys := ParseKeysList(*list)

	r, err := argf.From(flagset.Args())
	if err != nil {
		printErr(err)
		guideToHelp()
		os.Exit(2)
	}

	l := NewLTSVScanner(keys, r)
	l.OutputDelimiter = *outputDelimiter
	l.RemainLTSV = *remainLTSV
	if err := do(l); err != nil {
		printErr(err)
		os.Exit(1)
	}
	os.Exit(0)
}
<commit_msg>Use "if" instead of "switch" to check another one<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"os"

	"github.com/ogier/pflag"
	"github.com/yuya-takeyama/argf"
)

var (
	name    = "ltsvp"
	version = "0.5.0"

	flagset         = pflag.NewFlagSet(name, pflag.ContinueOnError)
	list            = flagset.StringP("keys", "k", "", "")
	outputDelimiter = flagset.StringP("output-delimiter", "D", "\t", "")
	remainLTSV      = flagset.BoolP("remain-ltsv", "r", false, "")
	isHelp          = flagset.BoolP("help", "h", false, "")
	isVersion       = flagset.BoolP("version", "v", false, "")
)

func printUsage() {
	fmt.Fprintf(os.Stderr, `
Usage: %s OPTION... [FILE]...
Print selected parts of LTSV from each FILE to standard output.

Options:
  -k, --keys=LIST
                 select only these keys (required)
  -D, --output-delimiter=STRING
                 use STRING to separate parts (default: \t)
  -r, --remain-ltsv
                 print selected parts as LTSV
  -h, --help
                 display this help text and exit
  -v, --version
                 output version information and exit

LIST is made up of keys separated by commas.
  host           # Select host
  host,time,ua   # Select host, time, and ua
`[1:], name)
}

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

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

func guideToHelp() {
	fmt.Fprintf(os.Stderr, "Try '%s --help' for more information.\n", name)
}

func do(l *LTSVScanner) error {
	for l.Scan() {
		fmt.Println(l.Text())
	}
	return l.Err()
}

func main() {
	flagset.SetOutput(ioutil.Discard)
	if err := flagset.Parse(os.Args[1:]); err != nil {
		printErr(err)
		guideToHelp()
		os.Exit(2)
	}
	if *isHelp {
		printUsage()
		os.Exit(0)
	}
	if *isVersion {
		printVersion()
		os.Exit(0)
	}

	specifiedList := false
	flagset.Visit(func(f *pflag.Flag) {
		if f.Name == "keys" {
			specifiedList = true
		}
	})
	if !specifiedList {
		printErr("no specify LIST")
		guideToHelp()
		os.Exit(2)
	}
	keys := ParseKeysList(*list)

	r, err := argf.From(flagset.Args())
	if err != nil {
		printErr(err)
		guideToHelp()
		os.Exit(2)
	}

	l := NewLTSVScanner(keys, r)
	l.OutputDelimiter = *outputDelimiter
	l.RemainLTSV = *remainLTSV
	if err := do(l); err != nil {
		printErr(err)
		os.Exit(1)
	}
	os.Exit(0)
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"net"
	"os"

	"github.com/joushou/sshmux"

	"golang.org/x/crypto/ssh"
)

func usage() {
	fmt.Printf("Usage: \n")
	fmt.Printf("   %s conf\n", os.Args[0])
}

type Host struct {
	Address string   `json:"address"`
	Users   []string `json:"users"`
	NoAuth  bool     `json:"noAuth"`
}

type Conf struct {
	Address  string `json:"address"`
	HostKey  string `json:"hostkey"`
	AuthKeys string `json:"authkeys"`
	Hosts    []Host `json:"hosts"`
}

func parseConf(filename string) (*Conf, error) {
	f, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}

	c := &Conf{}
	err = json.Unmarshal(f, c)
	if err != nil {
		return nil, err
	}

	return c, nil
}

func parseAuthFile(filename string) ([]*sshmux.User, error) {
	var users []*sshmux.User

	authFile, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}

	// Parse authfile as authorized_key

	for len(authFile) > 0 {
		var (
			pk      ssh.PublicKey
			comment string
		)

		pk, comment, _, authFile, err = ssh.ParseAuthorizedKey(authFile)
		if err != nil {
			return nil, err
		}

		u := &sshmux.User{
			PublicKey: pk,
			Name:      comment,
		}

		users = append(users, u)
	}

	return users, nil
}
func main() {
	if len(os.Args) != 2 {
		usage()
		return
	}

	conf := os.Args[1]

	c, err := parseConf(conf)
	if err != nil {
		panic(err)
	}

	hostPrivateKey, err := ioutil.ReadFile(c.HostKey)
	if err != nil {
		panic(err)
	}

	hostSigner, err := ssh.ParsePrivateKey(hostPrivateKey)
	if err != nil {
		panic(err)
	}

	users, err := parseAuthFile(c.AuthKeys)
	if err != nil {
		panic(err)
	}

	hasDefaults := false
	for _, h := range c.Hosts {
		if h.NoAuth {
			hasDefaults = true
			break
		}
	}

	auth := func(_ ssh.ConnMetadata, key ssh.PublicKey) (*sshmux.User, error) {
		t := key.Type()
		k := key.Marshal()
		for i := range users {
			candidate := users[i].PublicKey
			if t == candidate.Type() && bytes.Compare(k, candidate.Marshal()) == 0 {
				return users[i], nil
			}
		}

		if hasDefaults {
			return nil, nil
		}

		return nil, errors.New("access denied")
	}

	setup := func(session *sshmux.Session) error {
	outer:
		for _, h := range c.Hosts {
			if h.NoAuth {
				session.Remotes = append(session.Remotes, h.Address)
				continue outer
			}

			for _, u := range h.Users {
				if u == session.User.Name {
					session.Remotes = append(session.Remotes, h.Address)
					continue outer
				}
			}
		}
		return nil
	}

	server := sshmux.New(hostSigner, auth, setup)
	// Set up listener

	l, err := net.Listen("tcp", c.Address)
	if err != nil {
		panic(err)
	}

	server.Serve(l)
}
<commit_msg>Remove erroneous unused import<commit_after>package main

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net"
	"os"

	"github.com/joushou/sshmux"

	"golang.org/x/crypto/ssh"
)

func usage() {
	fmt.Printf("Usage: \n")
	fmt.Printf("   %s conf\n", os.Args[0])
}

type Host struct {
	Address string   `json:"address"`
	Users   []string `json:"users"`
	NoAuth  bool     `json:"noAuth"`
}

type Conf struct {
	Address  string `json:"address"`
	HostKey  string `json:"hostkey"`
	AuthKeys string `json:"authkeys"`
	Hosts    []Host `json:"hosts"`
}

func parseConf(filename string) (*Conf, error) {
	f, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}

	c := &Conf{}
	err = json.Unmarshal(f, c)
	if err != nil {
		return nil, err
	}

	return c, nil
}

func parseAuthFile(filename string) ([]*sshmux.User, error) {
	var users []*sshmux.User

	authFile, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}

	// Parse authfile as authorized_key

	for len(authFile) > 0 {
		var (
			pk      ssh.PublicKey
			comment string
		)

		pk, comment, _, authFile, err = ssh.ParseAuthorizedKey(authFile)
		if err != nil {
			return nil, err
		}

		u := &sshmux.User{
			PublicKey: pk,
			Name:      comment,
		}

		users = append(users, u)
	}

	return users, nil
}
func main() {
	if len(os.Args) != 2 {
		usage()
		return
	}

	conf := os.Args[1]

	c, err := parseConf(conf)
	if err != nil {
		panic(err)
	}

	hostPrivateKey, err := ioutil.ReadFile(c.HostKey)
	if err != nil {
		panic(err)
	}

	hostSigner, err := ssh.ParsePrivateKey(hostPrivateKey)
	if err != nil {
		panic(err)
	}

	users, err := parseAuthFile(c.AuthKeys)
	if err != nil {
		panic(err)
	}

	hasDefaults := false
	for _, h := range c.Hosts {
		if h.NoAuth {
			hasDefaults = true
			break
		}
	}

	auth := func(_ ssh.ConnMetadata, key ssh.PublicKey) (*sshmux.User, error) {
		t := key.Type()
		k := key.Marshal()
		for i := range users {
			candidate := users[i].PublicKey
			if t == candidate.Type() && bytes.Compare(k, candidate.Marshal()) == 0 {
				return users[i], nil
			}
		}

		if hasDefaults {
			return nil, nil
		}

		return nil, errors.New("access denied")
	}

	setup := func(session *sshmux.Session) error {
	outer:
		for _, h := range c.Hosts {
			if h.NoAuth {
				session.Remotes = append(session.Remotes, h.Address)
				continue outer
			}

			for _, u := range h.Users {
				if u == session.User.Name {
					session.Remotes = append(session.Remotes, h.Address)
					continue outer
				}
			}
		}
		return nil
	}

	server := sshmux.New(hostSigner, auth, setup)
	// Set up listener

	l, err := net.Listen("tcp", c.Address)
	if err != nil {
		panic(err)
	}

	server.Serve(l)
}
<|endoftext|>