<commit_before>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"log"
	"net/http"

	"gopkg.in/mgo.v2"
)

const (
	metricsPath = "/metrics"
	agentsPath  = "/agents"
)

var (
	ca *mgo.Collection
)

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

	var (
		addr = flag.String("addr", ":8080", "serve HTTP on `address`")
	)

	flag.Parse()

	http.HandleFunc(metricsPath, metricsHandler)
	http.HandleFunc(agentsPath, agentsHandler)
	http.Handle("/", http.FileServer(http.Dir("./public")))

	session, err := mgo.Dial("localhost")
	if err != nil {
		panic(err)
	}
	defer session.Close()

	// Optional. Switch the session to a monotonic behavior.
	session.SetMode(mgo.Monotonic, true)
	ca = session.DB("recon-dev").C("agents")

	log.Println("Server started: http://localhost" + *addr)
	log.Fatal(http.ListenAndServe(*addr, nil))
}

func metricsHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "TODO")
}

func agentsHandler(w http.ResponseWriter, r *http.Request) {
	switch r.Method {
	case "GET":
		var R []Agent
		err := ca.Find(nil).All(&R)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		enc := json.NewEncoder(w)
		if err := enc.Encode(R); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		return
	case "POST":
		var a Agent
		dec := json.NewDecoder(r.Body)
		if err := dec.Decode(&a); err != nil {
			http.Error(w, "unable to decode json", http.StatusBadRequest)
			return
		}
		if a.UID == "" {
			http.Error(w, "UID can't be empty", http.StatusBadRequest)
			return
		}
		err := ca.Insert(a)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		w.WriteHeader(http.StatusCreated)
		w.Write([]byte(a.UID))
		return
	default:
		http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
		return
	}
}

// Agent represents a recon agent running on
// a machine.
type Agent struct {
	UID string
}
<commit_msg>explicitly name URLs and code to specify an API<commit_after>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"log"
	"net/http"

	"gopkg.in/mgo.v2"
)

const (
	metricsAPIPath = "/api/metrics"
	agentsAPIPath  = "/api/agents"
)

var (
	ca *mgo.Collection
)

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

	var (
		addr = flag.String("addr", ":8080", "serve HTTP on `address`")
	)

	flag.Parse()

	http.HandleFunc(metricsAPIPath, metricsHandler)
	http.HandleFunc(agentsAPIPath, agentsHandler)
	http.Handle("/", http.FileServer(http.Dir("./public")))

	session, err := mgo.Dial("localhost")
	if err != nil {
		panic(err)
	}
	defer session.Close()

	// Optional. Switch the session to a monotonic behavior.
	session.SetMode(mgo.Monotonic, true)
	ca = session.DB("recon-dev").C("agents")

	log.Println("Server started: http://localhost" + *addr)
	log.Fatal(http.ListenAndServe(*addr, nil))
}

func metricsHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "TODO")
}

func agentsHandler(w http.ResponseWriter, r *http.Request) {
	switch r.Method {
	case "GET":
		var R []Agent
		err := ca.Find(nil).All(&R)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		enc := json.NewEncoder(w)
		if err := enc.Encode(R); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		return
	case "POST":
		var a Agent
		dec := json.NewDecoder(r.Body)
		if err := dec.Decode(&a); err != nil {
			http.Error(w, "unable to decode json", http.StatusBadRequest)
			return
		}
		if a.UID == "" {
			http.Error(w, "UID can't be empty", http.StatusBadRequest)
			return
		}
		err := ca.Insert(a)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		w.WriteHeader(http.StatusCreated)
		w.Write([]byte(a.UID))
		return
	default:
		http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
		return
	}
}

// Agent represents a recon agent running on
// a machine.
type Agent struct {
	UID string
}
<|endoftext|>


<commit_before>package main

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

	"github.com/codegangsta/cli"
	"github.com/koding/klientctl/logging"
	"github.com/koding/klientctl/util"
)

// ExitingCommand is a function that returns an exit code
type ExitingCommand func(*cli.Context) int

// ExitingWithMessageCommand is a function which prints the given message to
// Stdout. Useful for printig a message to the user in a convenient single-use way.
type ExitingWithMessageCommand func(*cli.Context) (string, int)

// sudoRequiredFor is the default list of commands that require sudo.
// The actual handling of this list is done in the SudoRequired func.
var sudoRequiredFor = []string{
	"install",
	"uninstall",
	"start",
	"stop",
	"restart",
	"update",
}

// log is used as a global loggger, for commands like ListCommand that
// need refactoring to support instance based commands.
//
// TODO: Remove this after all commands have been refactored into structs. Ie, the
// cli rewrite.
var log logging.Logger

func main() {
	var logWriter io.Writer
	f, err := os.OpenFile(LogFilePath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
	if err != nil {
		// TODO: We may not want to log a logfile failure here, but it seems useful to
		// give us some idea that the logs aren't being written.
		fmt.Println("Warning: Unable to load logfile")
		// Rather than exit `kd` because we are unable to log, we simple disable logging
		// by writing to /dev/null. This also measn that even if we can't load the log
		// file, the log instance is valid and doesn't have to be checked for being
		// nil before every usage.
		logWriter = ioutil.Discard
	} else {
		// TODO: Does defer get triggered on os.Exit? I think main() needs to be moved
		// to an alternate func that we can actuall use defer. Eg, main() calls Main(),
		// or something.
		defer f.Close()
		logWriter = f
	}

	log = logging.NewLogger("kd")
	log.SetHandler(logging.NewWriterHandler(logWriter))

	// Check if the command the user is giving requires sudo.
	if err := AdminRequired(os.Args, sudoRequiredFor, util.NewPermissions()); err != nil {
		// In the event of an error, simply print the error to the user
		// and exit.
		fmt.Println("Error: this command requires sudo.")
		os.Exit(10)
	}

	app := cli.NewApp()
	app.Name = Name
	app.Version = fmt.Sprintf("%d", Version)

	app.Commands = []cli.Command{
		cli.Command{
			Name:      "list",
			ShortName: "ls",
			Usage:     "List the available machines.",
			Action:    Exit(CheckUpdateFirst(ListCommand)),
			Subcommands: []cli.Command{
				cli.Command{
					Name:   "mounts",
					Usage:  "List the mounted machines.",
					Action: Exit(CheckUpdateFirst(MountsCommand)),
				},
			},
		},
		cli.Command{
			Name:        "mount",
			ShortName:   "m",
			Usage:       "Mount a remote folder to a local folder.",
			Description: cmdDescriptions["mount"],
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "remotepath, r",
					Usage: "Full path of remote folder in machine to mount.",
				},
				cli.BoolFlag{
					Name:  "noignore, n",
					Usage: "Disable ignoring of default remote folders.",
				},
				cli.BoolFlag{
					Name:  "noprefetch, p",
					Usage: "Disable prefetching of folder metadata on mount.",
				},
				cli.BoolFlag{
					Name:  "nowatch, w",
					Usage: "Disable watching for changes on remote machine.",
				},
			},
			Action: Exit(CheckUpdateFirst(MountCommand)),
		},
		cli.Command{
			Name:        "unmount",
			ShortName:   "u",
			Usage:       "Unmount previously mounted machine.",
			Description: cmdDescriptions["unmount"],
			Action:      Exit(CheckUpdateFirst(UnmountCommand)),
		},
		cli.Command{
			Name:        "ssh",
			ShortName:   "s",
			Usage:       "SSH into the machine.",
			Description: cmdDescriptions["ssh"],
			Action:      Exit(CheckUpdateFirst(SSHCommandFactory)),
		},
		cli.Command{
			Name:        "install",
			Usage:       fmt.Sprintf("Install the %s.", KlientName),
			Description: cmdDescriptions["install"],
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "kontrol, k",
					Usage: "Specify an alternate Kontrol",
				},
			},
			//HideHelp: true,
			Action: Exit(InstallCommandFactory),
		},
		cli.Command{
			Name:        "uninstall",
			Usage:       fmt.Sprintf("Uninstall the %s.", KlientName),
			Description: fmt.Sprintf("Uninstall the %s.", KlientName),
			Action:      ExitWithMessage(UninstallCommand),
		},
		cli.Command{
			Name:        "status",
			Usage:       fmt.Sprintf("Status of the %s.", KlientName),
			Description: fmt.Sprintf("Status the %s.", KlientName),
			Action:      Exit(StatusCommand),
		},
		cli.Command{
			Name:        "start",
			Usage:       fmt.Sprintf("Start the %s.", KlientName),
			Description: fmt.Sprintf("Start the %s.", KlientName),
			Action:      Exit(StartCommand),
		},
		cli.Command{
			Name:        "stop",
			Usage:       fmt.Sprintf("Stop the %s.", KlientName),
			Description: fmt.Sprintf("Stop the %s.", KlientName),
			Action:      Exit(StopCommand),
		},
		cli.Command{
			Name:        "restart",
			Usage:       fmt.Sprintf("Restart the %s.", KlientName),
			Description: fmt.Sprintf("Restart the %s.", KlientName),
			Action:      Exit(RestartCommand),
		},
		cli.Command{
			Name:        "update",
			Usage:       "Update to latest version.",
			Description: "Update to latest version.",
			Action:      Exit(UpdateCommand),
		},
		cli.Command{
			Name:            "run",
			Usage:           "Run command on remote or local machine.",
			Description:     cmdDescriptions["run"],
			Action:          Exit(RunCommandFactory),
			SkipFlagParsing: true,
		},
	}

	app.Run(os.Args)
}

// Exit is a wrapper around commands to return to proper error code.
func Exit(f ExitingCommand) func(*cli.Context) {
	return func(c *cli.Context) { os.Exit(f(c)) }
}

// ExitWithMessage takes a ExitingWithMessageCommand type and returns a
// codegansta/cli friendly command Action.
func ExitWithMessage(f ExitingWithMessageCommand) func(*cli.Context) {
	return func(c *cli.Context) {
		s, e := f(c)
		if s != "" {
			fmt.Println(s)
		}
		os.Exit(e)
	}
}
<commit_msg>logging: Logged the kd arg<commit_after>package main

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

	"github.com/codegangsta/cli"
	"github.com/koding/klientctl/logging"
	"github.com/koding/klientctl/util"
)

// ExitingCommand is a function that returns an exit code
type ExitingCommand func(*cli.Context) int

// ExitingWithMessageCommand is a function which prints the given message to
// Stdout. Useful for printig a message to the user in a convenient single-use way.
type ExitingWithMessageCommand func(*cli.Context) (string, int)

// sudoRequiredFor is the default list of commands that require sudo.
// The actual handling of this list is done in the SudoRequired func.
var sudoRequiredFor = []string{
	"install",
	"uninstall",
	"start",
	"stop",
	"restart",
	"update",
}

// log is used as a global loggger, for commands like ListCommand that
// need refactoring to support instance based commands.
//
// TODO: Remove this after all commands have been refactored into structs. Ie, the
// cli rewrite.
var log logging.Logger

func main() {
	var logWriter io.Writer
	f, err := os.OpenFile(LogFilePath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
	if err != nil {
		// TODO: We may not want to log a logfile failure here, but it seems useful to
		// give us some idea that the logs aren't being written.
		fmt.Println("Warning: Unable to load logfile")
		// Rather than exit `kd` because we are unable to log, we simple disable logging
		// by writing to /dev/null. This also measn that even if we can't load the log
		// file, the log instance is valid and doesn't have to be checked for being
		// nil before every usage.
		logWriter = ioutil.Discard
	} else {
		// TODO: Does defer get triggered on os.Exit? I think main() needs to be moved
		// to an alternate func that we can actuall use defer. Eg, main() calls Main(),
		// or something.
		defer f.Close()
		logWriter = f
	}

	log = logging.NewLogger("kd")
	log.SetHandler(logging.NewWriterHandler(logWriter))

	log.Infof("kd binary called with: %s", os.Args)

	// Check if the command the user is giving requires sudo.
	if err := AdminRequired(os.Args, sudoRequiredFor, util.NewPermissions()); err != nil {
		// In the event of an error, simply print the error to the user
		// and exit.
		fmt.Println("Error: this command requires sudo.")
		os.Exit(10)
	}

	app := cli.NewApp()
	app.Name = Name
	app.Version = fmt.Sprintf("%d", Version)

	app.Commands = []cli.Command{
		cli.Command{
			Name:      "list",
			ShortName: "ls",
			Usage:     "List the available machines.",
			Action:    Exit(CheckUpdateFirst(ListCommand)),
			Subcommands: []cli.Command{
				cli.Command{
					Name:   "mounts",
					Usage:  "List the mounted machines.",
					Action: Exit(CheckUpdateFirst(MountsCommand)),
				},
			},
		},
		cli.Command{
			Name:        "mount",
			ShortName:   "m",
			Usage:       "Mount a remote folder to a local folder.",
			Description: cmdDescriptions["mount"],
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "remotepath, r",
					Usage: "Full path of remote folder in machine to mount.",
				},
				cli.BoolFlag{
					Name:  "noignore, n",
					Usage: "Disable ignoring of default remote folders.",
				},
				cli.BoolFlag{
					Name:  "noprefetch, p",
					Usage: "Disable prefetching of folder metadata on mount.",
				},
				cli.BoolFlag{
					Name:  "nowatch, w",
					Usage: "Disable watching for changes on remote machine.",
				},
			},
			Action: Exit(CheckUpdateFirst(MountCommand)),
		},
		cli.Command{
			Name:        "unmount",
			ShortName:   "u",
			Usage:       "Unmount previously mounted machine.",
			Description: cmdDescriptions["unmount"],
			Action:      Exit(CheckUpdateFirst(UnmountCommand)),
		},
		cli.Command{
			Name:        "ssh",
			ShortName:   "s",
			Usage:       "SSH into the machine.",
			Description: cmdDescriptions["ssh"],
			Action:      Exit(CheckUpdateFirst(SSHCommandFactory)),
		},
		cli.Command{
			Name:        "install",
			Usage:       fmt.Sprintf("Install the %s.", KlientName),
			Description: cmdDescriptions["install"],
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "kontrol, k",
					Usage: "Specify an alternate Kontrol",
				},
			},
			//HideHelp: true,
			Action: Exit(InstallCommandFactory),
		},
		cli.Command{
			Name:        "uninstall",
			Usage:       fmt.Sprintf("Uninstall the %s.", KlientName),
			Description: fmt.Sprintf("Uninstall the %s.", KlientName),
			Action:      ExitWithMessage(UninstallCommand),
		},
		cli.Command{
			Name:        "status",
			Usage:       fmt.Sprintf("Status of the %s.", KlientName),
			Description: fmt.Sprintf("Status the %s.", KlientName),
			Action:      Exit(StatusCommand),
		},
		cli.Command{
			Name:        "start",
			Usage:       fmt.Sprintf("Start the %s.", KlientName),
			Description: fmt.Sprintf("Start the %s.", KlientName),
			Action:      Exit(StartCommand),
		},
		cli.Command{
			Name:        "stop",
			Usage:       fmt.Sprintf("Stop the %s.", KlientName),
			Description: fmt.Sprintf("Stop the %s.", KlientName),
			Action:      Exit(StopCommand),
		},
		cli.Command{
			Name:        "restart",
			Usage:       fmt.Sprintf("Restart the %s.", KlientName),
			Description: fmt.Sprintf("Restart the %s.", KlientName),
			Action:      Exit(RestartCommand),
		},
		cli.Command{
			Name:        "update",
			Usage:       "Update to latest version.",
			Description: "Update to latest version.",
			Action:      Exit(UpdateCommand),
		},
		cli.Command{
			Name:            "run",
			Usage:           "Run command on remote or local machine.",
			Description:     cmdDescriptions["run"],
			Action:          Exit(RunCommandFactory),
			SkipFlagParsing: true,
		},
	}

	app.Run(os.Args)
}

// Exit is a wrapper around commands to return to proper error code.
func Exit(f ExitingCommand) func(*cli.Context) {
	return func(c *cli.Context) { os.Exit(f(c)) }
}

// ExitWithMessage takes a ExitingWithMessageCommand type and returns a
// codegansta/cli friendly command Action.
func ExitWithMessage(f ExitingWithMessageCommand) func(*cli.Context) {
	return func(c *cli.Context) {
		s, e := f(c)
		if s != "" {
			fmt.Println(s)
		}
		os.Exit(e)
	}
}
<|endoftext|>


<commit_before>// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"fmt"
	"log"
	"net/http"
	"net/url"
	"os"
	"io/ioutil"

	"github.com/line/line-bot-sdk-go/linebot"
)

var bot *linebot.Client

func main() {
	var err error
	bot, err = linebot.New(os.Getenv("ChannelSecret"), os.Getenv("ChannelAccessToken"))
	log.Println("Bot:", bot, " err:", err)
	http.HandleFunc("/callback", callbackHandler)
	port := os.Getenv("PORT")
	addr := fmt.Sprintf(":%s", port)
	http.ListenAndServe(addr, nil)
}

func getSimsimi(word string) string{
	resp, err := http.Get("http://sandbox.api.simsimi.com/request.p?key=1b4f97fa-a422-45f0-8faf-0122ddd2dc5c&lc=id&ft=1.0&text=" + url.QueryEscape(word))
	if err != nil{
		log.Print(err)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	return string(body)
}

func callbackHandler(w http.ResponseWriter, r *http.Request) {
	events, err := bot.ParseRequest(r)

	if err != nil {
		if err == linebot.ErrInvalidSignature {
			w.WriteHeader(400)
		} else {
			w.WriteHeader(500)
		}
		return
	}

	for _, event := range events {
		if event.Type == linebot.EventTypeMessage {
			switch message := event.Message.(type) {
			case *linebot.TextMessage:
				if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(message.ID+":"+message.Text+" -> "+getSimsimi(message.Text))).Do(); err != nil {
					log.Print(err)
				}
			}
		}
	}
}
<commit_msg>json parsing<commit_after>// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"fmt"
	"log"
	"net/http"
	"net"
	"net/url"
	"os"
	"io/ioutil"

	"github.com/line/line-bot-sdk-go/linebot"
)

var bot *linebot.Client

func main() {
	var err error
	bot, err = linebot.New(os.Getenv("ChannelSecret"), os.Getenv("ChannelAccessToken"))
	log.Println("Bot:", bot, " err:", err)
	http.HandleFunc("/callback", callbackHandler)
	port := os.Getenv("PORT")
	addr := fmt.Sprintf(":%s", port)
	http.ListenAndServe(addr, nil)
}

func getSimsimi(word string) string{
	resp, err := http.Get("http://sandbox.api.simsimi.com/request.p?key=1b4f97fa-a422-45f0-8faf-0122ddd2dc5c&lc=id&ft=1.0&text=" + url.QueryEscape(word))
	if err != nil{
		log.Print(err)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	type resp2 struct {
    	Response string `json:"response"`
    	Id  string `json:"id"`
    	Result    string `json:"result"`
    	Msg  string `json:"msg"`
	}
	resp2 = resp2{}
	json.Unmarshal([]byte(body), &resp2)
	return string(resp2.Response[0])
}

func callbackHandler(w http.ResponseWriter, r *http.Request) {
	events, err := bot.ParseRequest(r)

	if err != nil {
		if err == linebot.ErrInvalidSignature {
			w.WriteHeader(400)
		} else {
			w.WriteHeader(500)
		}
		return
	}

	for _, event := range events {
		if event.Type == linebot.EventTypeMessage {
			switch message := event.Message.(type) {
			case *linebot.TextMessage:
				if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(message.ID+":"+message.Text+" -> "+getSimsimi(message.Text))).Do(); err != nil {
					log.Print(err)
				}
			}
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"math/rand"
	"os"
	"strconv"
	"time"
)

//VARIABILI
var Matrix [][]*Element
var Altezza int
var Larghezza int
var SaluteIniziale int = 50
var CostoMovIniziale int = 5
var CostoSexIniziale int = 50
var EvoluzioneIniziale int = 0
var PremuraIniziale int = 10
var AgeMaxInizio int = 30
var Clock uint
var NumClock uint

func main() { //FUNZIONE MAIN
	Clock = 1
	NumClock = 0
	rand.Seed(time.Now().UTC().UnixNano()) //inizializzazione rand
	height, err := strconv.Atoi(os.Args[1])
	if err != nil {
		panic("height not valid")
	}
	width, err2 := strconv.Atoi(os.Args[2])
	if err2 != nil {
		panic("width not valid")
	}
	Altezza = height
	Larghezza = width
	Matrix = make([][]*Element, height)
	for i := range Matrix { // inizializzazione matrice
		Matrix[i] = make([]*Element, width)
		for j := range Matrix[i] {
			chose := rand.Intn(3) //scelta rando cibo bug o vuoto (null)
			switch chose {
			case 0:
				Matrix[i][j] = new(Element) // insetto
				Matrix[i][j].IsFood = false
				Matrix[i][j].Age = 0
				Matrix[i][j].Health = SaluteIniziale
				Matrix[i][j].CostoMov = CostoMovIniziale
				Matrix[i][j].CostoSex = CostoSexIniziale
				Matrix[i][j].Evoluzione = EvoluzioneIniziale
				Matrix[i][j].Premura = PremuraIniziale
				Matrix[i][j].AgeMax = AgeMaxInizio
				Matrix[i][j].Razza = rand.Intn(2)
			case 1:
				Matrix[i][j] = nil //vuota
			case 2:
				Matrix[i][j] = new(Element) // cibo
				Matrix[i][j].IsFood = true
				Matrix[i][j].Health = 10
			}
		}
	}

	go ServiHTML() // fai partire il server html

	fmt.Println("Situazione iniziale: ")
	stampaMatrice()

	aggiorna()
}

func aggiorna() { //FUNZIONE AGGIORNA:	chiama la funzione muovi
	for {
		time.Sleep(time.Second * time.Duration(Clock))
		NumClock++
		for i := 0; i < Altezza; i++ {
			for j := 0; j < Larghezza; j++ {
				muovi(i, j)
			}
		}
		fmt.Printf("\nSituazione dopo %d movimenti:\n", NumClock)
		stampaMatrice()
	}
}

func muovi(h int, w int) { //FUNZIONE MUOVI:	aggiorna la posizione di tutti gli oggetti in tabella	// h verticale, w orizzontale
	elemento := Matrix[h][w]                //assegnamente del contenuto della cella in 'elemento'
	if elemento == nil || elemento.IsFood { //controllo se 'elemento' è cibo o un altro essere
		return
	}

	if elemento.Health<=0 {
		Matrix[h][w] = nil
		return
	} else {
		elemento.Age++
	}

	if elemento.Age>Matrix[h][w].AgeMax {
		Matrix[h][w] = nil
		return
	}
	direzCasOriz := rand.Intn(3) //numero da 0 a 2
	direzCasOriz--
	direzCasVert := rand.Intn(3)
	direzCasVert--
	nuovaPosizioneH := h + direzCasVert //aggiornamento posiozione verticale
	nuovaPosizioneW := w + direzCasOriz //aggiornamento posizione orizzontale

	if nuovaPosizioneH >= Altezza || nuovaPosizioneH < 0 ||
		nuovaPosizioneW >= Larghezza || nuovaPosizioneW < 0 { //se esce dai bordi
		return
	}

	if Matrix[nuovaPosizioneH][nuovaPosizioneW] != nil {
		if Matrix[nuovaPosizioneH][nuovaPosizioneW].Razza != Matrix[h][w].Razza { //se non è dalla stessa razza
			if Matrix[nuovaPosizioneH][nuovaPosizioneW].IsFood || (Matrix[nuovaPosizioneH][nuovaPosizioneW].Health+(Matrix[nuovaPosizioneH][nuovaPosizioneW].Evoluzione*5)) < (Matrix[h][w].Health+(Matrix[h][w].Evoluzione)*5) { // se e' cibo o un insetto piu debole
				Matrix[h][w].Health += Matrix[nuovaPosizioneH][nuovaPosizioneW].Health                //prelevamento energia essere fagocitato
				Matrix[nuovaPosizioneH][nuovaPosizioneW] = Matrix[h][w] //inglobamento essere perito
				Matrix[h][w] = nil
				Matrix[nuovaPosizioneH][nuovaPosizioneW].Health -= (Matrix[nuovaPosizioneH][nuovaPosizioneW].CostoMov-(Matrix[nuovaPosizioneH][nuovaPosizioneW].Evoluzione))
			} else {	//perdita nel combattimento per la sopravvivenza
				Matrix[nuovaPosizioneH][nuovaPosizioneW].Health += Matrix[h][w].Health //il nemico prende l'energia
				Matrix[h][w] = nil
			}
		} else { //se sono amici
			if nuovaPosizioneH == h && nuovaPosizioneW == w { //se cerca di mangiare il suo amico
				muovi(h, w)
			}
		}
	} else { //si muove sulla nuova casella
		Matrix[nuovaPosizioneH][nuovaPosizioneW] = Matrix[h][w]
		Matrix[nuovaPosizioneH][nuovaPosizioneW].Health -= Matrix[nuovaPosizioneH][nuovaPosizioneW].CostoMov-(Matrix[nuovaPosizioneH][nuovaPosizioneW].Evoluzione)
		Matrix[h][w] = nil

		if rand.Intn(10) == 0 { //se ha fortuna (o sfortuna) si evolve
			if rand.Intn(3) == 0 {
				Matrix[nuovaPosizioneH][nuovaPosizioneW].Evoluzione--
				Matrix[nuovaPosizioneH][nuovaPosizioneW].AgeMax-=5
			} else {
				Matrix[nuovaPosizioneH][nuovaPosizioneW].Evoluzione++
				Matrix[nuovaPosizioneH][nuovaPosizioneW].AgeMax+=10
			}
		}

		if (Matrix[nuovaPosizioneH][nuovaPosizioneW].Health-(Matrix[nuovaPosizioneH][nuovaPosizioneW].Premura)*10)>Matrix[nuovaPosizioneH][nuovaPosizioneW].CostoSex {		//se ha energia a sufficienza per riprodursi
			Matrix[h][w] = Costruttore(Matrix[nuovaPosizioneH][nuovaPosizioneW].Razza, Matrix[nuovaPosizioneH][nuovaPosizioneW].Evoluzione, Matrix[nuovaPosizioneH][nuovaPosizioneW].CostoMov, Matrix[nuovaPosizioneH][nuovaPosizioneW].CostoSex, Matrix[nuovaPosizioneH][nuovaPosizioneW].Premura, SaluteIniziale, AgeMaxInizio)
		}

	}

}

func stampaMatrice() {
	for i := 0; i < Altezza; i++ {
		for j := 0; j < Larghezza; j++ {
			if Matrix[i][j] == nil {
				fmt.Printf("   --  ")
			} else {
				if Matrix[i][j].IsFood {
					fmt.Printf("   CC  ")
				} else {
					fmt.Printf("%d   %d  ",Matrix[i][j].Razza, Matrix[i][j].Health)
				}
			}
		}
		fmt.Printf("\n")
	}
}
<commit_msg>ciclo di carnaut eliminato<commit_after>package main

import (
	"fmt"
	"math/rand"
	"os"
	"strconv"
	"time"
)

//VARIABILI
var Matrix [][]*Element
var Altezza int
var Larghezza int
var SaluteIniziale int = 50
var CostoMovIniziale int = 5
var CostoSexIniziale int = 50
var EvoluzioneIniziale int = 0
var PremuraIniziale int = 10
var AgeMaxInizio int = 30
var Clock uint
var NumClock uint

func main() { //FUNZIONE MAIN
	Clock = 1
	NumClock = 0
	rand.Seed(time.Now().UTC().UnixNano()) //inizializzazione rand
	height, err := strconv.Atoi(os.Args[1])
	if err != nil {
		panic("height not valid")
	}
	width, err2 := strconv.Atoi(os.Args[2])
	if err2 != nil {
		panic("width not valid")
	}
	Altezza = height
	Larghezza = width
	Matrix = make([][]*Element, height)
	for i := range Matrix { // inizializzazione matrice
		Matrix[i] = make([]*Element, width)
		for j := range Matrix[i] {
			chose := rand.Intn(3) //scelta rando cibo bug o vuoto (null)
			switch chose {
			case 0:
				Matrix[i][j] = new(Element) // insetto
				Matrix[i][j].IsFood = false
				Matrix[i][j].Age = 0
				Matrix[i][j].Health = SaluteIniziale
				Matrix[i][j].CostoMov = CostoMovIniziale
				Matrix[i][j].CostoSex = CostoSexIniziale
				Matrix[i][j].Evoluzione = EvoluzioneIniziale
				Matrix[i][j].Premura = PremuraIniziale
				Matrix[i][j].AgeMax = AgeMaxInizio
				Matrix[i][j].Razza = rand.Intn(2)
			case 1:
				Matrix[i][j] = nil //vuota
			case 2:
				Matrix[i][j] = new(Element) // cibo
				Matrix[i][j].IsFood = true
				Matrix[i][j].Health = 10
			}
		}
	}

	go ServiHTML() // fai partire il server html

	fmt.Println("Situazione iniziale: ")
	stampaMatrice()

	aggiorna()
}

func aggiorna() { //FUNZIONE AGGIORNA:	chiama la funzione muovi
	for {
		time.Sleep(time.Second * time.Duration(Clock))
		NumClock++
		for i := 0; i < Altezza; i++ {
			for j := 0; j < Larghezza; j++ {
				muovi(i, j)
			}
		}
		fmt.Printf("\nSituazione dopo %d movimenti:\n", NumClock)
		stampaMatrice()
	}
}

func muovi(h int, w int) { //FUNZIONE MUOVI:	aggiorna la posizione di tutti gli oggetti in tabella	// h verticale, w orizzontale
	elemento := Matrix[h][w]                //assegnamente del contenuto della cella in 'elemento'
	if elemento == nil || elemento.IsFood { //controllo se 'elemento' è cibo o un altro essere
		return
	}

	if elemento.Health<=0 {
		Matrix[h][w] = nil
		return
	} else {
		elemento.Age++
	}

	if elemento.Age>Matrix[h][w].AgeMax {
		Matrix[h][w] = nil
		return
	}
	direzCasOriz := rand.Intn(3) //numero da 0 a 2
	direzCasOriz--
	direzCasVert := rand.Intn(3)
	direzCasVert--
	nuovaPosizioneH := h + direzCasVert //aggiornamento posiozione verticale
	nuovaPosizioneW := w + direzCasOriz //aggiornamento posizione orizzontale

	if nuovaPosizioneH >= Altezza || nuovaPosizioneH < 0 ||
		nuovaPosizioneW >= Larghezza || nuovaPosizioneW < 0 { //se esce dai bordi
		return
	}

	if Matrix[nuovaPosizioneH][nuovaPosizioneW] != nil {
		if Matrix[nuovaPosizioneH][nuovaPosizioneW].Razza != Matrix[h][w].Razza { //se non è dalla stessa razza
			if Matrix[nuovaPosizioneH][nuovaPosizioneW].IsFood || (Matrix[nuovaPosizioneH][nuovaPosizioneW].Health+(Matrix[nuovaPosizioneH][nuovaPosizioneW].Evoluzione*5)) < (Matrix[h][w].Health+(Matrix[h][w].Evoluzione)*5) { // se e' cibo o un insetto piu debole
				Matrix[h][w].Health += Matrix[nuovaPosizioneH][nuovaPosizioneW].Health                //prelevamento energia essere fagocitato
				Matrix[nuovaPosizioneH][nuovaPosizioneW] = Matrix[h][w] //inglobamento essere perito
				Matrix[h][w] = nil
				Matrix[nuovaPosizioneH][nuovaPosizioneW].Health -= (Matrix[nuovaPosizioneH][nuovaPosizioneW].CostoMov)
			} else {	//perdita nel combattimento per la sopravvivenza
				Matrix[nuovaPosizioneH][nuovaPosizioneW].Health += Matrix[h][w].Health //il nemico prende l'energia
				Matrix[h][w] = nil
			}
		} else { //se sono amici
			if nuovaPosizioneH == h && nuovaPosizioneW == w { //se cerca di mangiare il suo amico
				muovi(h, w)
			}
		}
	} else { //si muove sulla nuova casella
		Matrix[nuovaPosizioneH][nuovaPosizioneW] = Matrix[h][w]
		Matrix[nuovaPosizioneH][nuovaPosizioneW].Health -= Matrix[nuovaPosizioneH][nuovaPosizioneW].CostoMov
		Matrix[h][w] = nil

		if rand.Intn(10) == 0 { //se ha fortuna (o sfortuna) si evolve
			if rand.Intn(3) == 0 {
				Matrix[nuovaPosizioneH][nuovaPosizioneW].Evoluzione--
				Matrix[nuovaPosizioneH][nuovaPosizioneW].AgeMax-=5
			} else {
				Matrix[nuovaPosizioneH][nuovaPosizioneW].Evoluzione++
				Matrix[nuovaPosizioneH][nuovaPosizioneW].AgeMax+=10
			}
		}

		if (Matrix[nuovaPosizioneH][nuovaPosizioneW].Health-(Matrix[nuovaPosizioneH][nuovaPosizioneW].Premura)*10)>Matrix[nuovaPosizioneH][nuovaPosizioneW].CostoSex {		//se ha energia a sufficienza per riprodursi
			Matrix[h][w] = Costruttore(Matrix[nuovaPosizioneH][nuovaPosizioneW].Razza, Matrix[nuovaPosizioneH][nuovaPosizioneW].Evoluzione, Matrix[nuovaPosizioneH][nuovaPosizioneW].CostoMov, Matrix[nuovaPosizioneH][nuovaPosizioneW].CostoSex, Matrix[nuovaPosizioneH][nuovaPosizioneW].Premura, SaluteIniziale, AgeMaxInizio)
		}

	}

}

func stampaMatrice() {
	for i := 0; i < Altezza; i++ {
		for j := 0; j < Larghezza; j++ {
			if Matrix[i][j] == nil {
				fmt.Printf("   --  ")
			} else {
				if Matrix[i][j].IsFood {
					fmt.Printf("   CC  ")
				} else {
					fmt.Printf("%d   %d  ",Matrix[i][j].Razza, Matrix[i][j].Health)
				}
			}
		}
		fmt.Printf("\n")
	}
}
<|endoftext|>


<commit_before>// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"fmt"
	"log"
	"net/http"
	"os"
	"database/sql"

	"github.com/line/line-bot-sdk-go/linebot"
	"github.com/NoahShen/go-simsimi"
	 _ "github.com/go-sql-driver/mysql"
)

var bot *linebot.Client
var session *simsimi.SimSimiSession
func main() {
	var err error
	session, _ = simsimi.CreateSimSimiSession("Wallte")
	bot, err = linebot.New(os.Getenv("CHANNEL_SECRET"), os.Getenv("CHANNEL_TOKEN"))
	log.Println("Bot:", bot, " err:", err)
	http.HandleFunc("/callback", callbackHandler)
	port := os.Getenv("PORT")
	addr := fmt.Sprintf(":%s", port)
	http.ListenAndServe(addr, nil)
}

func connect() (*sql.DB, error) {
	db, err := sql.Open("mysql", os.Getenv("DB_CONNECT"))
	if err != nil {
		fmt.Println(err.Error())
		return nil, err
	}
	return db, nil
}

func callbackHandler(w http.ResponseWriter, r *http.Request) {
	events, err := bot.ParseRequest(r)

	if err != nil {
		if err == linebot.ErrInvalidSignature {
			w.WriteHeader(400)
		} else {
			w.WriteHeader(500)
		}
		return
	}

	for _, event := range events {
		if event.Type == linebot.EventTypeMessage {
			switch message := event.Message.(type) {
			case *linebot.TextMessage:
				/*if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(message.ID+":"+message.Text+" OK!")).Do(); err != nil {
					log.Print(err)
				}*/
				imageURL := "https://drive.google.com/file/d/0Bx6cTEFypiiNaHVTcXV5VkFpbFE/view?usp=sharing"
				template := linebot.NewButtonsTemplate(
					imageURL, "My button sample"+message.Text, "Hello, my button",
					linebot.NewURITemplateAction("Go to line.me", "https://line.me"),
					linebot.NewPostbackTemplateAction("Say hello1", "hello こんにちは", ""),
					linebot.NewPostbackTemplateAction("言 hello2", "hello こんにちは", "hello こんにちは"),
					linebot.NewMessageTemplateAction("Say message", "Rice=米"),
				)
				if _, err := bot.ReplyMessage(
					event.ReplyToken,
					linebot.NewTemplateMessage("Buttons alt text", template),
				).Do(); err != nil {
					return
				}

				responseText, _ := session.Talk(message.Text)
				if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(responseText)).Do(); err != nil {
					log.Print(err)
				}

			}
		}else if event.Type == linebot.EventTypePostback{
			/*if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage("iniPostback")).Do(); err != nil {
					log.Print(err)
				}*/

			imageURL := "https://github.com/AdityaMili95/Wallte/blob/master/README/qI5Ujdy9n1.png"
			/*template := linebot.NewCarouselTemplate(
				linebot.NewCarouselColumn(
					imageURL, "hoge", "fuga",
					linebot.NewURITemplateAction("Go to line.me", "https://line.me"),
					linebot.NewPostbackTemplateAction("Say hello1", "hello こんにちは", ""),
				),
				linebot.NewCarouselColumn(
					imageURL, "hoge", "fuga",
					linebot.NewPostbackTemplateAction("言 hello2", "hello こんにちは", "hello こんにちは"),
					linebot.NewMessageTemplateAction("Say message", "Rice=米"),
				),
			)
			if _, err := bot.ReplyMessage(
				event.ReplyToken,
				linebot.NewTemplateMessage("Carousel alt text", template),
			).Do(); err != nil {
				log.Print(err)
			}*/
			template := linebot.NewImageCarouselTemplate(
				linebot.NewImageCarouselColumn(
					imageURL,
					linebot.NewURITemplateAction("Go to LINE", "https://line.me"),
				),
				linebot.NewImageCarouselColumn(
					imageURL,
					linebot.NewPostbackTemplateAction("Say hello1", "hello こんにちは", ""),
				),
				linebot.NewImageCarouselColumn(
					imageURL,
					linebot.NewMessageTemplateAction("Say message", "Rice=米"),
				),
				linebot.NewImageCarouselColumn(
					imageURL,
					linebot.NewDatetimePickerTemplateAction("datetime", "DATETIME", "datetime", "", "", ""),
				),
			)
			if _, err := bot.ReplyMessage(
				event.ReplyToken,
				linebot.NewTemplateMessage("Image carousel alt text", template),
			).Do(); err != nil {
				log.Print(err)
			}

			/*template := linebot.NewButtonsTemplate(
				"", "", "Select date / time !",
				linebot.NewDatetimePickerTemplateAction("date", "DATE", "date", "", "", ""),
				linebot.NewDatetimePickerTemplateAction("time", "TIME", "time", "", "", ""),
				linebot.NewDatetimePickerTemplateAction("datetime", "DATETIME", "datetime", "", "", ""),
			)
			if _, err := bot.ReplyMessage(
				event.ReplyToken,
				linebot.NewTemplateMessage("Datetime pickers alt text", template),
			).Do(); err != nil {
				log.Print(err)
			}*/

		}

	}
}
<commit_msg>get user data<commit_after>// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"fmt"
	"log"
	"net/http"
	"os"
	"database/sql"

	"github.com/line/line-bot-sdk-go/linebot"
	"github.com/NoahShen/go-simsimi"
	 _ "github.com/go-sql-driver/mysql"
)

var bot *linebot.Client
var session *simsimi.SimSimiSession
func main() {
	var err error
	session, _ = simsimi.CreateSimSimiSession("Wallte")
	bot, err = linebot.New(os.Getenv("CHANNEL_SECRET"), os.Getenv("CHANNEL_TOKEN"))
	log.Println("Bot:", bot, " err:", err)
	http.HandleFunc("/callback", callbackHandler)
	port := os.Getenv("PORT")
	addr := fmt.Sprintf(":%s", port)
	http.ListenAndServe(addr, nil)
}

func connect() (*sql.DB, error) {
	db, err := sql.Open("mysql", os.Getenv("DB_CONNECT"))
	if err != nil {
		fmt.Println(err.Error())
		return nil, err
	}
	return db, nil
}

func callbackHandler(w http.ResponseWriter, r *http.Request) {
	events, err := bot.ParseRequest(r)

	if err != nil {
		if err == linebot.ErrInvalidSignature {
			w.WriteHeader(400)
		} else {
			w.WriteHeader(500)
		}
		return
	}

	for _, event := range events {
		if event.Type == linebot.EventTypeMessage {
			switch message := event.Message.(type) {
			case *linebot.TextMessage:
				/*if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(message.ID+":"+message.Text+" OK!")).Do(); err != nil {
					log.Print(err)
				}*/
				imageURL := "https://drive.google.com/file/d/0Bx6cTEFypiiNaHVTcXV5VkFpbFE/view?usp=sharing"
				template := linebot.NewButtonsTemplate(
					imageURL, "My button sample"+message.Text, "Hello, my button",
					linebot.NewURITemplateAction("Go to line.me", "https://line.me"),
					linebot.NewPostbackTemplateAction("Say hello1", "hello こんにちは", ""),
					linebot.NewPostbackTemplateAction("言 hello2", "hello こんにちは", "hello こんにちは"),
					linebot.NewMessageTemplateAction("Say message", "Rice=米"),
				)
				if _, err := bot.ReplyMessage(
					event.ReplyToken,
					linebot.NewTemplateMessage("Buttons alt text", template),
				).Do(); err != nil {
					return
				}

				responseText, _ := session.Talk(message.Text)
				if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(responseText)).Do(); err != nil {
					log.Print(err)
				}

			}
		}else if event.Type == linebot.EventTypePostback{
			/*if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage("iniPostback")).Do(); err != nil {
					log.Print(err)
				}*/

			imageURL := "https://github.com/AdityaMili95/Wallte/blob/master/README/qI5Ujdy9n1.png"
			/*template := linebot.NewCarouselTemplate(
				linebot.NewCarouselColumn(
					imageURL, "hoge", "fuga",
					linebot.NewURITemplateAction("Go to line.me", "https://line.me"),
					linebot.NewPostbackTemplateAction("Say hello1", "hello こんにちは", ""),
				),
				linebot.NewCarouselColumn(
					imageURL, "hoge", "fuga",
					linebot.NewPostbackTemplateAction("言 hello2", "hello こんにちは", "hello こんにちは"),
					linebot.NewMessageTemplateAction("Say message", "Rice=米"),
				),
			)
			if _, err := bot.ReplyMessage(
				event.ReplyToken,
				linebot.NewTemplateMessage("Carousel alt text", template),
			).Do(); err != nil {
				log.Print(err)
			}*/

			profile, err := bot.GetProfile(event.Source.UserID).Do()
			if(err!=nil){
				log.Print(err)
				return;
			}
			template := linebot.NewImageCarouselTemplate(
				linebot.NewImageCarouselColumn(
					imageURL,
					linebot.NewURITemplateAction("Go to LINE", "https://line.me"),
				),
				linebot.NewImageCarouselColumn(
					imageURL,
					linebot.NewPostbackTemplateAction("Say hello1", "hello こんにちは", "Hello"+profile.UserID),
				),
				linebot.NewImageCarouselColumn(
					imageURL,
					linebot.NewMessageTemplateAction("Say message", "Rice=米"),
				),
				linebot.NewImageCarouselColumn(
					imageURL,
					linebot.NewDatetimePickerTemplateAction("datetime", "DATETIME", "datetime", "", "", ""),
				),
			)
			if _, err := bot.ReplyMessage(
				event.ReplyToken,
				linebot.NewTemplateMessage("Image carousel alt text", template),
			).Do(); err != nil {
				log.Print(err)
			}

			/*template := linebot.NewButtonsTemplate(
				"", "", "Select date / time !",
				linebot.NewDatetimePickerTemplateAction("date", "DATE", "date", "", "", ""),
				linebot.NewDatetimePickerTemplateAction("time", "TIME", "time", "", "", ""),
				linebot.NewDatetimePickerTemplateAction("datetime", "DATETIME", "datetime", "", "", ""),
			)
			if _, err := bot.ReplyMessage(
				event.ReplyToken,
				linebot.NewTemplateMessage("Datetime pickers alt text", template),
			).Do(); err != nil {
				log.Print(err)
			}*/

		}

	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/Sirupsen/logrus"
	"github.com/Songmu/prompter"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/service/iam"
	"github.com/olekukonko/tablewriter"
	"gopkg.in/alecthomas/kingpin.v2"
	"io/ioutil"
	"os"
	"time"
)

func AWSConfig(key, secret, token, file, profile string) (conf *aws.Config) {
	var creds *credentials.Credentials
	if file != "" {
		creds = credentials.NewSharedCredentials(file, profile)
	}
	if key != "" && secret != "" {
		creds = credentials.NewStaticCredentials(key, secret, token)
	}

	conf = &aws.Config{
		Credentials: creds,
	}

	return conf
}

func ReadFile(fpath string) (body string, err error) {
	var f *os.File
	var b []byte

	f, err = os.Open(fpath)
	if err != nil {
		return body, err
	}

	b, err = ioutil.ReadAll(f)
	if err != nil {
		return body, err
	}

	return string(b), err
}

func CertificateBody(cb, cbPath string) (body string, err error) {
	if cbPath != "" {
		body, err = ReadFile(cbPath)
	} else {
		body = cb
	}

	return body, err
}

func PrivateKey(pk, pkPath string) (body string, err error) {
	if pkPath != "" {
		body, err = ReadFile(pkPath)
	} else {
		body = pk
	}

	return body, err
}

func CertificateChain(cc, ccPath string) (body string, err error) {
	if ccPath != "" {
		body, err = ReadFile(ccPath)
	} else {
		body = cc
	}

	return body, err
}

func UploadServerCertificateInput(cBody, cChain, path, pKey, sCert string) (uploadSCInput *iam.UploadServerCertificateInput) {
	uploadSCInput = &iam.UploadServerCertificateInput{
		CertificateBody:       aws.String(cBody),
		CertificateChain:      aws.String(cChain),
		Path:                  aws.String(path),
		PrivateKey:            aws.String(pKey),
		ServerCertificateName: aws.String(sCert),
	}

	return uploadSCInput
}

func UpdateServerCertificateInput(newPath, newSCert, sCert string) (updateSCInput *iam.UpdateServerCertificateInput) {
	updateSCInput = &iam.UpdateServerCertificateInput{
		NewPath:                  aws.String(newPath),
		NewServerCertificateName: aws.String(newSCert),
		ServerCertificateName:    aws.String(sCert),
	}

	return updateSCInput
}

func ListServerCertificatesInput(marker string, mexItems int, pathPrefix string) (listSCInput *iam.ListServerCertificatesInput) {
	listSCInput = &iam.ListServerCertificatesInput{}

	if marker != "" {
		listSCInput.Marker = aws.String(marker)
	}

	maxItems64 := int64(*maxItems)

	if maxItems64 > 0 {
		listSCInput.MaxItems = aws.Int64(maxItems64)
	}

	if pathPrefix != "" {
		listSCInput.PathPrefix = aws.String(pathPrefix)
	}

	return listSCInput
}

func RetrieveNames(list *iam.ListServerCertificatesOutput) (names []string) {
	for _, metadata := range list.ServerCertificateMetadataList {
		names = append(names, *metadata.ServerCertificateName)
	}
	return names
}

func Timezone(zone string) (location *time.Location) {
	location = time.FixedZone(zone, 9*60*60)
	return location
}

func FormatedTime(t time.Time, zone *time.Location) (fTime string) {
	return t.In(zone).Format("2006-01-02 15:04:05 -0700")
}

func OutputList(list *iam.ListServerCertificatesOutput) {
	table := tablewriter.NewWriter(os.Stdout)
	table.SetHeader([]string{"Arn", "Path", "ServerCertificateId", "ServerCertificateName", "UploadDate", "Expiration"})
	zone := Timezone(*timezone)
	for _, metadata := range list.ServerCertificateMetadataList {
		uploadDate := FormatedTime(*metadata.UploadDate, zone)
		expiration := FormatedTime(*metadata.Expiration, zone)
		data := []string{
			*metadata.Arn, *metadata.Path, *metadata.ServerCertificateId, *metadata.ServerCertificateName,
			fmt.Sprint(uploadDate), fmt.Sprint(expiration),
		}
		table.Append(data)
	}
	table.Render()
}

var (
	iamSrvCert            = kingpin.New("iam-server-cert", "(List|Upload|Update|Delete) the server certificates for the AWS account")
	serverCertificateName = iamSrvCert.Flag("server-certificate-name", "The name for the server certificate").String()
	certificateBody       = iamSrvCert.Flag("certificate-body", "The contents of the public key certificate in PEM-encoded format").String()
	privateKey            = iamSrvCert.Flag("private-key", "The contents of the private key in PEM-encoded format").String()
	certificateChain      = iamSrvCert.Flag("certificate-chain", "The contents of the certificate chain").String()
	certificateBodyPath   = iamSrvCert.Flag("certificate-body-path", "Path to public key certificate").String()
	privateKeyPath        = iamSrvCert.Flag("private-key-path", "Path to private key").String()
	certificateChainPath  = iamSrvCert.Flag("certificate-chain-path", "Path to certificate chain").String()
	accessKey             = iamSrvCert.Flag("access-key", "AWS access key").String()
	accessSecret          = iamSrvCert.Flag("access-secret", "AWS secret key").String()
	token                 = iamSrvCert.Flag("token", "Session token").String()
	credentialsPath       = iamSrvCert.Flag("credentials", "Credential file").String()
	profile               = iamSrvCert.Flag("profile", "Use a specific profile from your credential file").Default("default").String()
	timezone              = iamSrvCert.Flag("timezone", "Timezone").Default("UTC").String()

	iamSrvCertList   = iamSrvCert.Command("list", "List SSL certificates")
	marker           = iamSrvCertList.Flag("marker", "Paginating results and only after you receive a response indicating that the results are truncated").String()
	maxItems         = iamSrvCertList.Flag("max-items", "The total number of items to return").Int()
	pathPrefix       = iamSrvCertList.Flag("path-prefix", "The path prefix for filtering the results").Default("/").String()
	iamSrvCertDelete = iamSrvCert.Command("delete", "Delete SSL certificate")

	iamSrvCertUpload = iamSrvCert.Command("upload", "Upload SSL certificate")
	uploadPath       = iamSrvCertUpload.Flag("path", "The path for the server certificate").Default("/").String()

	iamSrvCertUpdate         = iamSrvCert.Command("update", "Update SSL certificate")
	newPath                  = iamSrvCertUpdate.Flag("new-path", "The new path for the server certificate").String()
	newServerCertificateName = iamSrvCertUpdate.Flag("new-server-certificate-name", "The new name for the server certificate").String()

	iamSvc *iam.IAM
)

func main() {
	iamSrvCert.Version("0.0.1")
	subCmd, err := iamSrvCert.Parse(os.Args[1:])

	iamSvc = iam.New(AWSConfig(*accessKey, *accessSecret, *token, *credentialsPath, *profile))
	log := logrus.New()

	switch subCmd {
	case "upload":
		cBody, err := CertificateBody(*certificateBody, *certificateBodyPath)
		if err != nil {
			log.Fatal(err)
		}

		pKey, err := PrivateKey(*privateKey, *privateKeyPath)
		if err != nil {
			log.Fatal(err)
		}

		cChain, err := CertificateChain(*certificateChain, *certificateChainPath)
		if err != nil {
			log.Fatal(err)
		}

		uploadSCInput := UploadServerCertificateInput(cBody, cChain, *uploadPath, pKey, *serverCertificateName)

		_, err = iamSvc.UploadServerCertificate(uploadSCInput)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println("Uploaded", *serverCertificateName)
	case "update":
		updateSCInput := UpdateServerCertificateInput(*newPath, *newServerCertificateName, *serverCertificateName)

		_, err = iamSvc.UpdateServerCertificate(updateSCInput)
		if err != nil {
			log.Fatal(err)
		}

		fmt.Println("Updated from", *serverCertificateName, "to", *newServerCertificateName)
	case "list":
		var lscOut *iam.ListServerCertificatesOutput
		lscOut, err = iamSvc.ListServerCertificates(ListServerCertificatesInput(*marker, *maxItems, *pathPrefix))
		if err != nil {
			log.Fatal(err)
		}

		OutputList(lscOut)
	case "delete":
		var lscOut *iam.ListServerCertificatesOutput
		lscOut, err = iamSvc.ListServerCertificates(ListServerCertificatesInput(*marker, *maxItems, *pathPrefix))
		if err != nil {
			log.Fatal(err)
		}

		names := RetrieveNames(lscOut)

		var cert string
		if *serverCertificateName != "" {
			cert = *serverCertificateName
		} else {
			cert = (&prompter.Prompter{
				Choices:    names,
				UseDefault: false,
				Message:    "Choose the server certificate you want to delete.",
				IgnoreCase: true,
			}).Prompt()
		}

		_, err = iamSvc.DeleteServerCertificate(&iam.DeleteServerCertificateInput{ServerCertificateName: aws.String(cert)})
		if err != nil {
			log.Fatal(err)
		}

		fmt.Println("Deleted", cert)
	}
}
<commit_msg>timezone -> time-offset<commit_after>package main

import (
	"fmt"
	"github.com/Sirupsen/logrus"
	"github.com/Songmu/prompter"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/service/iam"
	"github.com/olekukonko/tablewriter"
	"gopkg.in/alecthomas/kingpin.v2"
	"io/ioutil"
	"os"
	"time"
)

func AWSConfig(key, secret, token, file, profile string) (conf *aws.Config) {
	var creds *credentials.Credentials
	if file != "" {
		creds = credentials.NewSharedCredentials(file, profile)
	}
	if key != "" && secret != "" {
		creds = credentials.NewStaticCredentials(key, secret, token)
	}

	conf = &aws.Config{
		Credentials: creds,
	}

	return conf
}

func ReadFile(fpath string) (body string, err error) {
	var f *os.File
	var b []byte

	f, err = os.Open(fpath)
	if err != nil {
		return body, err
	}

	b, err = ioutil.ReadAll(f)
	if err != nil {
		return body, err
	}

	return string(b), err
}

func CertificateBody(cb, cbPath string) (body string, err error) {
	if cbPath != "" {
		body, err = ReadFile(cbPath)
	} else {
		body = cb
	}

	return body, err
}

func PrivateKey(pk, pkPath string) (body string, err error) {
	if pkPath != "" {
		body, err = ReadFile(pkPath)
	} else {
		body = pk
	}

	return body, err
}

func CertificateChain(cc, ccPath string) (body string, err error) {
	if ccPath != "" {
		body, err = ReadFile(ccPath)
	} else {
		body = cc
	}

	return body, err
}

func UploadServerCertificateInput(cBody, cChain, path, pKey, sCert string) (uploadSCInput *iam.UploadServerCertificateInput) {
	uploadSCInput = &iam.UploadServerCertificateInput{
		CertificateBody:       aws.String(cBody),
		CertificateChain:      aws.String(cChain),
		Path:                  aws.String(path),
		PrivateKey:            aws.String(pKey),
		ServerCertificateName: aws.String(sCert),
	}

	return uploadSCInput
}

func UpdateServerCertificateInput(newPath, newSCert, sCert string) (updateSCInput *iam.UpdateServerCertificateInput) {
	updateSCInput = &iam.UpdateServerCertificateInput{
		NewPath:                  aws.String(newPath),
		NewServerCertificateName: aws.String(newSCert),
		ServerCertificateName:    aws.String(sCert),
	}

	return updateSCInput
}

func ListServerCertificatesInput(marker string, mexItems int, pathPrefix string) (listSCInput *iam.ListServerCertificatesInput) {
	listSCInput = &iam.ListServerCertificatesInput{}

	if marker != "" {
		listSCInput.Marker = aws.String(marker)
	}

	maxItems64 := int64(*maxItems)

	if maxItems64 > 0 {
		listSCInput.MaxItems = aws.Int64(maxItems64)
	}

	if pathPrefix != "" {
		listSCInput.PathPrefix = aws.String(pathPrefix)
	}

	return listSCInput
}

func RetrieveNames(list *iam.ListServerCertificatesOutput) (names []string) {
	for _, metadata := range list.ServerCertificateMetadataList {
		names = append(names, *metadata.ServerCertificateName)
	}
	return names
}

func Timezone(offset int) (location *time.Location) {
	location = time.FixedZone("", offset*60*60)
	return location
}

func FormatedTime(t time.Time, zone *time.Location) (fTime string) {
	return t.In(zone).Format("2006-01-02 15:04:05 -0700")
}

func OutputList(list *iam.ListServerCertificatesOutput, offset int) {
	table := tablewriter.NewWriter(os.Stdout)
	table.SetHeader([]string{"Arn", "Path", "ServerCertificateId", "ServerCertificateName", "UploadDate", "Expiration"})
	zone := Timezone(offset)
	for _, metadata := range list.ServerCertificateMetadataList {
		uploadDate := FormatedTime(*metadata.UploadDate, zone)
		expiration := FormatedTime(*metadata.Expiration, zone)
		data := []string{
			*metadata.Arn, *metadata.Path, *metadata.ServerCertificateId, *metadata.ServerCertificateName,
			fmt.Sprint(uploadDate), fmt.Sprint(expiration),
		}
		table.Append(data)
	}
	table.Render()
}

var (
	iamSrvCert            = kingpin.New("iam-server-cert", "(List|Upload|Update|Delete) the server certificates for the AWS account")
	serverCertificateName = iamSrvCert.Flag("server-certificate-name", "The name for the server certificate").String()
	certificateBody       = iamSrvCert.Flag("certificate-body", "The contents of the public key certificate in PEM-encoded format").String()
	privateKey            = iamSrvCert.Flag("private-key", "The contents of the private key in PEM-encoded format").String()
	certificateChain      = iamSrvCert.Flag("certificate-chain", "The contents of the certificate chain").String()
	certificateBodyPath   = iamSrvCert.Flag("certificate-body-path", "Path to public key certificate").String()
	privateKeyPath        = iamSrvCert.Flag("private-key-path", "Path to private key").String()
	certificateChainPath  = iamSrvCert.Flag("certificate-chain-path", "Path to certificate chain").String()
	accessKey             = iamSrvCert.Flag("access-key", "AWS access key").String()
	accessSecret          = iamSrvCert.Flag("access-secret", "AWS secret key").String()
	token                 = iamSrvCert.Flag("token", "Session token").String()
	credentialsPath       = iamSrvCert.Flag("credentials", "Credential file").String()
	profile               = iamSrvCert.Flag("profile", "Use a specific profile from your credential file").Default("default").String()

	iamSrvCertList = iamSrvCert.Command("list", "List SSL certificates")
	marker         = iamSrvCertList.Flag("marker", "Paginating results and only after you receive a response indicating that the results are truncated").String()
	maxItems       = iamSrvCertList.Flag("max-items", "The total number of items to return").Int()
	pathPrefix     = iamSrvCertList.Flag("path-prefix", "The path prefix for filtering the results").Default("/").String()
	timeOffset     = iamSrvCertList.Flag("time-offset", "Time offsets").Default("0").Int()

	iamSrvCertDelete = iamSrvCert.Command("delete", "Delete SSL certificate")

	iamSrvCertUpload = iamSrvCert.Command("upload", "Upload SSL certificate")
	uploadPath       = iamSrvCertUpload.Flag("path", "The path for the server certificate").Default("/").String()

	iamSrvCertUpdate         = iamSrvCert.Command("update", "Update SSL certificate")
	newPath                  = iamSrvCertUpdate.Flag("new-path", "The new path for the server certificate").String()
	newServerCertificateName = iamSrvCertUpdate.Flag("new-server-certificate-name", "The new name for the server certificate").String()

	iamSvc *iam.IAM
)

func main() {
	iamSrvCert.Version("0.0.1")
	subCmd, err := iamSrvCert.Parse(os.Args[1:])

	iamSvc = iam.New(AWSConfig(*accessKey, *accessSecret, *token, *credentialsPath, *profile))
	log := logrus.New()

	switch subCmd {
	case "upload":
		cBody, err := CertificateBody(*certificateBody, *certificateBodyPath)
		if err != nil {
			log.Fatal(err)
		}

		pKey, err := PrivateKey(*privateKey, *privateKeyPath)
		if err != nil {
			log.Fatal(err)
		}

		cChain, err := CertificateChain(*certificateChain, *certificateChainPath)
		if err != nil {
			log.Fatal(err)
		}

		uploadSCInput := UploadServerCertificateInput(cBody, cChain, *uploadPath, pKey, *serverCertificateName)

		_, err = iamSvc.UploadServerCertificate(uploadSCInput)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println("Uploaded", *serverCertificateName)
	case "update":
		updateSCInput := UpdateServerCertificateInput(*newPath, *newServerCertificateName, *serverCertificateName)

		_, err = iamSvc.UpdateServerCertificate(updateSCInput)
		if err != nil {
			log.Fatal(err)
		}

		fmt.Println("Updated from", *serverCertificateName, "to", *newServerCertificateName)
	case "list":
		var lscOut *iam.ListServerCertificatesOutput
		lscOut, err = iamSvc.ListServerCertificates(ListServerCertificatesInput(*marker, *maxItems, *pathPrefix))
		if err != nil {
			log.Fatal(err)
		}

		OutputList(lscOut, *timeOffset)
	case "delete":
		var lscOut *iam.ListServerCertificatesOutput
		lscOut, err = iamSvc.ListServerCertificates(ListServerCertificatesInput(*marker, *maxItems, *pathPrefix))
		if err != nil {
			log.Fatal(err)
		}

		names := RetrieveNames(lscOut)

		var cert string
		if *serverCertificateName != "" {
			cert = *serverCertificateName
		} else {
			cert = (&prompter.Prompter{
				Choices:    names,
				UseDefault: false,
				Message:    "Choose the server certificate you want to delete.",
				IgnoreCase: true,
			}).Prompt()
		}

		_, err = iamSvc.DeleteServerCertificate(&iam.DeleteServerCertificateInput{ServerCertificateName: aws.String(cert)})
		if err != nil {
			log.Fatal(err)
		}

		fmt.Println("Deleted", cert)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"flag"
	"fmt"
	"math/rand"
	"net"
	"os"
	"reflect"
	"strings"
	"sync"
)

var wordList []string

// This is a cache of the mapping of domains to their wildcard addresses, e.g.
// *.example.com is stored as ["example.com"] = [127.0.0.1]
var wildcardRegistry map[string][]string
var wildcardRegistryMutex sync.RWMutex

var outputType string

// Whether this is the first line of output to print
var outputFirst bool

func main() {
	// Parse cmdline
	flag_domain := flag.String("domain", "", "The target domain")
	flag_wordlist := flag.String("wordlist", "wordlist.txt", "Path to the wordlist")
	flag_threads := flag.Int("threads", 20, "Number of concurrent threads")
	flag_output := flag.String("output", "csv", "Output type (csv, json)")

	flag.Parse()

	if *flag_domain == "" {
		fmt.Fprint(os.Stderr, "You must specify a domain\r\n")
		flag.PrintDefaults()
		os.Exit(1)
	}

	outputType = strings.ToLower(*flag_output)
	outputFirst = true

	switch outputType {
	case "csv":
	case "json":
	default:
		fmt.Fprintf(os.Stderr, "Invalid output format specified\r\n")
		flag.PrintDefaults()
		os.Exit(1)
	}

	file, err := os.Open(*flag_wordlist)
	if err != nil {
		panic(err)
	}

	// Make our new wildcard map
	wildcardRegistry = make(map[string][]string)
	// Check for wildcard record(s) before starting
	wildcardDetected := checkWildcard(*flag_domain)

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		wordList = append(wordList, scanner.Text())
	}

	queue := make(chan string, *flag_threads)
	done := resolveList(queue, *flag_domain, wildcardDetected)
	<-done
}

func resolveList(queue chan string, apex string, wildcardDetected bool) chan bool {
	doneChan := make(chan bool)
	go func() {
		// Create a waitgroup for all of the child threads we'll spawn
		var childrenWait sync.WaitGroup
		for i := range wordList {
			domainName := fmt.Sprintf("%s.%s", wordList[i], apex)

			// wait for free worker thread
			queue <- domainName
			// Add an item to the WaitGroup
			childrenWait.Add(1)
			go func() {
				// Defer removing ourselves from the WaitGroup once we're complete
				defer childrenWait.Done()

				ips, err := net.LookupHost(domainName)
				// we have looked up the host, so we can remove this item from the queue
				// so that another go routine can give it a go
				<-queue

				// did not resolve
				if err != nil {
					// TODO: find a nicer way of writing this
					errstr := err.Error()
					nsh := "no such host"
					if errstr[len(errstr)-len(nsh):] != nsh {
						fmt.Fprintf(os.Stderr, "Unexpected error: %v\n", err)
					}
					return
				}

				// Check if it's a wildcard
				if wildcardDetected {
					// Read lock the mutex
					wildcardRegistryMutex.RLock()
					if reflect.DeepEqual(ips, wildcardRegistry[apex]) {
						// Not a real finding -- see note about the bug at wildcard definition
						wildcardRegistryMutex.RUnlock()
						return
					}
					wildcardRegistryMutex.RUnlock()
				}

				// we found a non-wildcard sub domain, recurse
				outputResult(domainName, ips)
				childDone := resolveList(queue, domainName, checkWildcard(domainName))
				// wait for child to finish
				<-childDone
			}()
		}
		// Wait for all children to complete
		childrenWait.Wait()

		// Signal we're done
		doneChan <- true
	}()
	return doneChan
}

func checkWildcard(domain string) bool {
	// Check for wildcard record(s)
	randomString := randomString(10)
	wildcard, _ := net.LookupHost(randomString + "." + domain)
	if len(wildcard) > 0 {
		fmt.Fprintf(os.Stderr, "Detected wildcard record: %s\r\n", domain)
		// Lock for writing
		wildcardRegistryMutex.Lock()
		wildcardRegistry[domain] = wildcard
		wildcardRegistryMutex.Unlock()
		return true
	}
	return false
}

func outputResult(domain string, ips []string) {
	switch outputType {
	case "json":
		if outputFirst {
			fmt.Printf("{\r\n")
			outputFirst = false
		} else {
			fmt.Printf(",\r\n")
		}
		fmt.Printf("{\"%s\": {\"%s\"}}", domain, strings.Join(ips, "\",\""))
	case "csv":
		fmt.Printf("%s,%s\r\n", domain, strings.Join(ips, ","))
	}
}

func randomString(length int) string {
	letterRunes := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
	b := make([]rune, length)
	for i := range b {
		b[i] = letterRunes[rand.Intn(len(letterRunes))]
	}
	return string(b)
}
<commit_msg>Refactor wildcard state to remove mutex/hashmap<commit_after>package main

import (
	"bufio"
	"flag"
	"fmt"
	"math/rand"
	"net"
	"os"
	"reflect"
	"strings"
	"sync"
)

var wordList []string

var outputType string

// Whether this is the first line of output to print
var outputFirst bool

func main() {
	// Parse cmdline
	flag_domain := flag.String("domain", "", "The target domain")
	flag_wordlist := flag.String("wordlist", "wordlist.txt", "Path to the wordlist")
	flag_threads := flag.Int("threads", 20, "Number of concurrent threads")
	flag_output := flag.String("output", "csv", "Output type (csv, json)")

	flag.Parse()

	if *flag_domain == "" {
		fmt.Fprint(os.Stderr, "You must specify a domain\r\n")
		flag.PrintDefaults()
		os.Exit(1)
	}

	outputType = strings.ToLower(*flag_output)
	outputFirst = true

	switch outputType {
	case "csv":
	case "json":
	default:
		fmt.Fprintf(os.Stderr, "Invalid output format specified\r\n")
		flag.PrintDefaults()
		os.Exit(1)
	}

	file, err := os.Open(*flag_wordlist)
	if err != nil {
		panic(err)
	}

	// Check for wildcard record(s) before starting
	wildcard := checkWildcard(*flag_domain)

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		wordList = append(wordList, scanner.Text())
	}

	queue := make(chan string, *flag_threads)
	done := resolveList(queue, *flag_domain, wildcard)
	<-done
}

func resolveList(queue chan string, apex string, wildcard []string) chan bool {
	doneChan := make(chan bool)
	go func() {
		// Create a waitgroup for all of the child threads we'll spawn
		var childrenWait sync.WaitGroup
		for i := range wordList {
			domainName := fmt.Sprintf("%s.%s", wordList[i], apex)

			// wait for free worker thread
			queue <- domainName
			// Add an item to the WaitGroup
			childrenWait.Add(1)
			go func() {
				// Defer removing ourselves from the WaitGroup once we're complete
				defer childrenWait.Done()

				ips, err := net.LookupHost(domainName)
				// we have looked up the host, so we can remove this item from the queue
				// so that another go routine can give it a go
				<-queue

				// did not resolve
				if err != nil {
					// TODO: find a nicer way of writing this
					errstr := err.Error()
					nsh := "no such host"
					if errstr[len(errstr)-len(nsh):] != nsh {
						fmt.Fprintf(os.Stderr, "Unexpected error: %v\n", err)
					}
					return
				}

				// Check if it's a wildcard
				if len(wildcard) > 0 {
					if reflect.DeepEqual(ips, wildcard) {
						return
					}
				}

				// we found a non-wildcard sub domain, recurse
				outputResult(domainName, ips)
				childDone := resolveList(queue, domainName, checkWildcard(domainName))
				// wait for child to finish
				<-childDone
			}()
		}
		// Wait for all children to complete
		childrenWait.Wait()

		// Signal we're done
		doneChan <- true
	}()
	return doneChan
}

func checkWildcard(domain string) (wildcard []string) {
	// Check for wildcard record(s)
	randomString := randomString(10)
	wildcard, _ = net.LookupHost(randomString + "." + domain)
	if len(wildcard) > 0 {
		fmt.Fprintf(os.Stderr, "Detected wildcard record: %s\r\n", domain)
	}
	return
}

func outputResult(domain string, ips []string) {
	switch outputType {
	case "json":
		if outputFirst {
			fmt.Printf("{\r\n")
			outputFirst = false
		} else {
			fmt.Printf(",\r\n")
		}
		fmt.Printf("{\"%s\": {\"%s\"}}", domain, strings.Join(ips, "\",\""))
	case "csv":
		fmt.Printf("%s,%s\r\n", domain, strings.Join(ips, ","))
	}
}

func randomString(length int) string {
	letterRunes := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
	b := make([]rune, length)
	for i := range b {
		b[i] = letterRunes[rand.Intn(len(letterRunes))]
	}
	return string(b)
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"time"

	humanize "github.com/dustin/go-humanize"
	"github.com/schollz/croc/src/croc"
	"github.com/schollz/croc/src/utils"
	"github.com/urfave/cli"
)

var version string
var codePhrase string

var cr *croc.Croc

func main() {
	app := cli.NewApp()
	app.Name = "croc"
	if version == "" {
		version = "dev"
	}

	app.Version = version
	app.Compiled = time.Now()
	app.Usage = "easily and securely transfer stuff from one computer to another"
	app.UsageText = "croc allows any two computers to directly and securely transfer files"
	// app.ArgsUsage = "[args and such]"
	app.Commands = []cli.Command{
		{
			Name:        "send",
			Usage:       "send a file",
			Description: "send a file over the relay",
			ArgsUsage:   "[filename]",
			Flags: []cli.Flag{
				cli.BoolFlag{Name: "no-compress, o", Usage: "disable compression"},
				cli.BoolFlag{Name: "no-encrypt, e", Usage: "disable encryption"},
				cli.StringFlag{Name: "code, c", Usage: "codephrase used to connect to relay"},
			},
			HelpName: "croc send",
			Action: func(c *cli.Context) error {
				return send(c)
			},
		},
		{
			Name:        "relay",
			Usage:       "start a croc relay",
			Description: "the croc relay will handle websocket and TCP connections",
			Flags:       []cli.Flag{},
			HelpName:    "croc relay",
			Action: func(c *cli.Context) error {
				return relay(c)
			},
		},
	}
	app.Flags = []cli.Flag{
		cli.StringFlag{Name: "relay", Value: "ws://croc4.schollz.com"},
		cli.BoolFlag{Name: "no-local", Usage: "disable local mode"},
		cli.BoolFlag{Name: "local", Usage: "use only local mode"},
		cli.BoolFlag{Name: "debug", Usage: "increase verbosity (a lot)"},
		cli.BoolFlag{Name: "yes", Usage: "automatically agree to all prompts"},
		cli.BoolFlag{Name: "stdout", Usage: "redirect file to stdout"},
		cli.StringFlag{Name: "port", Value: "8153", Usage: "port that the websocket listens on"},
		cli.StringFlag{Name: "curve", Value: "siec", Usage: "specify elliptic curve to use (p224, p256, p384, p521, siec)"},
	}
	app.EnableBashCompletion = true
	app.HideHelp = false
	app.HideVersion = false
	app.BashComplete = func(c *cli.Context) {
		fmt.Fprintf(c.App.Writer, "send\nreceive\relay")
	}
	app.Action = func(c *cli.Context) error {
		return receive(c)
	}
	app.Before = func(c *cli.Context) error {
		cr = croc.Init(c.GlobalBool("debug"))
		cr.AllowLocalDiscovery = true
		cr.WebsocketAddress = c.GlobalString("relay")
		cr.NoRecipientPrompt = c.GlobalBool("yes")
		cr.Stdout = c.GlobalBool("stdout")
		cr.LocalOnly = c.GlobalBool("local")
		cr.NoLocal = c.GlobalBool("no-local")
		cr.ShowText = true
		cr.ServerPort = c.String("port")
		cr.CurveType = c.String("curve")
		return nil
	}

	err := app.Run(os.Args)
	if err != nil {
		fmt.Printf("\nerror: %s", err.Error())
	}
}

func send(c *cli.Context) error {
	stat, _ := os.Stdin.Stat()
	var fname string
	if (stat.Mode() & os.ModeCharDevice) == 0 {
		f, err := ioutil.TempFile(".", "croc-stdin-")
		if err != nil {
			return err
		}
		_, err = io.Copy(f, os.Stdin)
		if err != nil {
			return err
		}
		err = f.Close()
		if err != nil {
			return err
		}
		fname = f.Name()
		defer func() {
			log.Println("removing %s", fname)
			err = os.Remove(fname)
			if err != nil {
				log.Println(err)
			}
		}()
	} else {
		fname = c.Args().First()
	}
	if fname == "" {
		return errors.New("must specify file: croc send [filename]")
	}
	cr.UseCompression = !c.Bool("no-compress")
	cr.UseEncryption = !c.Bool("no-encrypt")
	if c.String("code") != "" {
		codePhrase = c.String("code")
	}
	if len(codePhrase) == 0 {
		// generate code phrase
		codePhrase = utils.GetRandomName()
	}

	// print the text
	finfo, err := os.Stat(fname)
	if err != nil {
		return err
	}
	fname, _ = filepath.Abs(fname)
	fname = filepath.Clean(fname)
	_, filename := filepath.Split(fname)
	fileOrFolder := "file"
	fsize := finfo.Size()
	if finfo.IsDir() {
		fileOrFolder = "folder"
		fsize, err = dirSize(fname)
		if err != nil {
			return err
		}
	}
	fmt.Fprintf(os.Stderr,
		"Sending %s %s named '%s'\nCode is: %s\nOn the other computer, please run:\n\ncroc %s\n\n",
		humanize.Bytes(uint64(fsize)),
		fileOrFolder,
		filename,
		codePhrase,
		codePhrase,
	)
	return cr.Send(fname, codePhrase)
}

func receive(c *cli.Context) error {
	if c.GlobalString("code") != "" {
		codePhrase = c.GlobalString("code")
	}
	if c.Args().First() != "" {
		codePhrase = c.Args().First()
	}
	if codePhrase == "" {
		codePhrase = utils.GetInput("Enter receive code: ")
	}
	return cr.Receive(codePhrase)
}

func relay(c *cli.Context) error {
	return cr.Relay()
}

func dirSize(path string) (int64, error) {
	var size int64
	err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error {
		if !info.IsDir() {
			size += info.Size()
		}
		return err
	})
	return size, err
}
<commit_msg>use direct address<commit_after>package main

import (
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"time"

	humanize "github.com/dustin/go-humanize"
	"github.com/schollz/croc/src/croc"
	"github.com/schollz/croc/src/utils"
	"github.com/urfave/cli"
)

var version string
var codePhrase string

var cr *croc.Croc

func main() {
	app := cli.NewApp()
	app.Name = "croc"
	if version == "" {
		version = "dev"
	}

	app.Version = version
	app.Compiled = time.Now()
	app.Usage = "easily and securely transfer stuff from one computer to another"
	app.UsageText = "croc allows any two computers to directly and securely transfer files"
	// app.ArgsUsage = "[args and such]"
	app.Commands = []cli.Command{
		{
			Name:        "send",
			Usage:       "send a file",
			Description: "send a file over the relay",
			ArgsUsage:   "[filename]",
			Flags: []cli.Flag{
				cli.BoolFlag{Name: "no-compress, o", Usage: "disable compression"},
				cli.BoolFlag{Name: "no-encrypt, e", Usage: "disable encryption"},
				cli.StringFlag{Name: "code, c", Usage: "codephrase used to connect to relay"},
			},
			HelpName: "croc send",
			Action: func(c *cli.Context) error {
				return send(c)
			},
		},
		{
			Name:        "relay",
			Usage:       "start a croc relay",
			Description: "the croc relay will handle websocket and TCP connections",
			Flags:       []cli.Flag{},
			HelpName:    "croc relay",
			Action: func(c *cli.Context) error {
				return relay(c)
			},
		},
	}
	app.Flags = []cli.Flag{
		cli.StringFlag{Name: "relay", Value: "ws://198.199.67.130:8153"},
		cli.BoolFlag{Name: "no-local", Usage: "disable local mode"},
		cli.BoolFlag{Name: "local", Usage: "use only local mode"},
		cli.BoolFlag{Name: "debug", Usage: "increase verbosity (a lot)"},
		cli.BoolFlag{Name: "yes", Usage: "automatically agree to all prompts"},
		cli.BoolFlag{Name: "stdout", Usage: "redirect file to stdout"},
		cli.StringFlag{Name: "port", Value: "8153", Usage: "port that the websocket listens on"},
		cli.StringFlag{Name: "curve", Value: "siec", Usage: "specify elliptic curve to use (p224, p256, p384, p521, siec)"},
	}
	app.EnableBashCompletion = true
	app.HideHelp = false
	app.HideVersion = false
	app.BashComplete = func(c *cli.Context) {
		fmt.Fprintf(c.App.Writer, "send\nreceive\relay")
	}
	app.Action = func(c *cli.Context) error {
		return receive(c)
	}
	app.Before = func(c *cli.Context) error {
		cr = croc.Init(c.GlobalBool("debug"))
		cr.AllowLocalDiscovery = true
		cr.WebsocketAddress = c.GlobalString("relay")
		cr.NoRecipientPrompt = c.GlobalBool("yes")
		cr.Stdout = c.GlobalBool("stdout")
		cr.LocalOnly = c.GlobalBool("local")
		cr.NoLocal = c.GlobalBool("no-local")
		cr.ShowText = true
		cr.ServerPort = c.String("port")
		cr.CurveType = c.String("curve")
		return nil
	}

	err := app.Run(os.Args)
	if err != nil {
		fmt.Printf("\nerror: %s", err.Error())
	}
}

func send(c *cli.Context) error {
	stat, _ := os.Stdin.Stat()
	var fname string
	if (stat.Mode() & os.ModeCharDevice) == 0 {
		f, err := ioutil.TempFile(".", "croc-stdin-")
		if err != nil {
			return err
		}
		_, err = io.Copy(f, os.Stdin)
		if err != nil {
			return err
		}
		err = f.Close()
		if err != nil {
			return err
		}
		fname = f.Name()
		defer func() {
			log.Println("removing %s", fname)
			err = os.Remove(fname)
			if err != nil {
				log.Println(err)
			}
		}()
	} else {
		fname = c.Args().First()
	}
	if fname == "" {
		return errors.New("must specify file: croc send [filename]")
	}
	cr.UseCompression = !c.Bool("no-compress")
	cr.UseEncryption = !c.Bool("no-encrypt")
	if c.String("code") != "" {
		codePhrase = c.String("code")
	}
	if len(codePhrase) == 0 {
		// generate code phrase
		codePhrase = utils.GetRandomName()
	}

	// print the text
	finfo, err := os.Stat(fname)
	if err != nil {
		return err
	}
	fname, _ = filepath.Abs(fname)
	fname = filepath.Clean(fname)
	_, filename := filepath.Split(fname)
	fileOrFolder := "file"
	fsize := finfo.Size()
	if finfo.IsDir() {
		fileOrFolder = "folder"
		fsize, err = dirSize(fname)
		if err != nil {
			return err
		}
	}
	fmt.Fprintf(os.Stderr,
		"Sending %s %s named '%s'\nCode is: %s\nOn the other computer, please run:\n\ncroc %s\n\n",
		humanize.Bytes(uint64(fsize)),
		fileOrFolder,
		filename,
		codePhrase,
		codePhrase,
	)
	return cr.Send(fname, codePhrase)
}

func receive(c *cli.Context) error {
	if c.GlobalString("code") != "" {
		codePhrase = c.GlobalString("code")
	}
	if c.Args().First() != "" {
		codePhrase = c.Args().First()
	}
	if codePhrase == "" {
		codePhrase = utils.GetInput("Enter receive code: ")
	}
	return cr.Receive(codePhrase)
}

func relay(c *cli.Context) error {
	return cr.Relay()
}

func dirSize(path string) (int64, error) {
	var size int64
	err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error {
		if !info.IsDir() {
			size += info.Size()
		}
		return err
	})
	return size, err
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"errors"
	"flag"
	"github.com/gorilla/context"
	"github.com/gorilla/sessions"
	"golang.org/x/oauth2"
	"golang.org/x/oauth2/facebook"
	"log"
	"net/http"
	"os"
	"strconv"
	"strings"
)

type FbrpConfig struct {
	AppId         string `json:"app_id"`
	AppSecret     string `json:"app_secret"`
	Hostname      string `json:"hostname"`
	SecretGroupId string `json:"secret_group_id"`
	ServeRoot     string `json:"serve_root"`
	InternalPort  int    `json:"internal_port"`
	SessionSecret string `json:"session_secret"`
}

var CONFIG FbrpConfig

var store *sessions.CookieStore
var SESSION_NAME = "session-name"
var COOKIE_HAS_AUTH = "hasAuth"

var FACEBOOK_OAUTH_CONFIG oauth2.Config
var FACEBOOK_AUTH_CALLBACK_ROUTE = "/auth/login/facebook/callback"

func init() {
	var configFile = flag.String("config", "./fbrp.config", "config file location")
	flag.Parse()
	log.Println("reading config from:", *configFile)
	file, err := os.Open(*configFile)
	if err != nil {
		panic(err)
	}
	decoder := json.NewDecoder(file)
	decoder.Decode(&CONFIG)

	log.Println(CONFIG)

	if CONFIG.SessionSecret == "" {
		panic("SessionSecret should never be empty")
	}
	store = sessions.NewCookieStore([]byte(CONFIG.SessionSecret))

	FACEBOOK_OAUTH_CONFIG = oauth2.Config{
		ClientID:     CONFIG.AppId,
		ClientSecret: CONFIG.AppSecret,
		RedirectURL:  "http://" + CONFIG.Hostname + FACEBOOK_AUTH_CALLBACK_ROUTE,
		Scopes:       []string{"user_about_me,user_groups"},
		Endpoint:     facebook.Endpoint,
	}
}

func handleFiles(prefix string) http.Handler {
	fs := http.FileServer(http.Dir(CONFIG.ServeRoot))
	return http.StripPrefix(prefix, fs)
}

func requireAuth(innerHandler http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		session, _ := store.Get(r, SESSION_NAME)
		v, ok := session.Values[COOKIE_HAS_AUTH]
		if ok && v.(bool) {
			innerHandler.ServeHTTP(w, r)
		} else {
			w.WriteHeader(403)
			serveString("You're not logged in, login first").ServeHTTP(w, r)
		}
	})
}

func promptFacebookLogin() http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		facebookLoginUrl := FACEBOOK_OAUTH_CONFIG.AuthCodeURL("login")
		http.Redirect(w, r, facebookLoginUrl, 301)
	})
}

func checkFacebookGroups(token *oauth2.Token) (bool, error) {
	client := FACEBOOK_OAUTH_CONFIG.Client(oauth2.NoContext, token)
	resp, err := client.Get("https://graph.facebook.com/me?fields=id,name,groups{id}")
	if err != nil {
		log.Println("failed to check groups")
		log.Println(err)
		return false, err
	}
	defer resp.Body.Close()

	var respData map[string]interface{}

	_ = json.NewDecoder(resp.Body).Decode(&respData)

	name := respData["name"].(string)
	listOfGroups := respData["groups"].(map[string]interface{})
	listOfGroups2 := listOfGroups["data"].([]interface{})

	for _, group := range listOfGroups2 {
		groupId := group.(map[string]interface{})["id"].(string)
		if groupId == CONFIG.SecretGroupId {
			log.Println("LOGIN: ", name)
			return true, nil
		}
	}
	return false, errors.New("You don't belong to the secret group, sorry!")
}

func handleFacebookAuth() http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		code := r.FormValue("code")
		token, _ := FACEBOOK_OAUTH_CONFIG.Exchange(oauth2.NoContext, code)

		userAllowed, err := checkFacebookGroups(token)
		if err != nil {
			serveString("something bad happened: "+err.Error()).ServeHTTP(w, r)
		}

		if userAllowed {
			login(w, r)
		} else {
			logout(w, r)
		}

		http.Redirect(w, r, "/", 301)
	})
}

func handleLogout() http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		logout(w, r)
		http.Redirect(w, r, "/", 301)
	})
}

func serveString(message string) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		isLoggedInStr := "yes!"
		if !isLoggedIn(r) {
			isLoggedInStr = "No!"
		}
		contents := strings.Replace(CONTENTS, "[[[LOGGED IN]]]", isLoggedInStr, 1)
		contents = strings.Replace(contents, "[[[MESSAGE]]]", message, 1)
		w.Write([]byte(contents))
	})
}

func login(w http.ResponseWriter, r *http.Request) {
	session, _ := store.Get(r, SESSION_NAME)
	session.Values[COOKIE_HAS_AUTH] = true
	session.Save(r, w)
}

func logout(w http.ResponseWriter, r *http.Request) {
	session, _ := store.Get(r, SESSION_NAME)
	session.Values[COOKIE_HAS_AUTH] = false
	session.Save(r, w)
}

func isLoggedIn(r *http.Request) bool {
	session, _ := store.Get(r, SESSION_NAME)
	authd, ok := session.Values[COOKIE_HAS_AUTH]
	if ok && authd.(bool) {
		return true
	}
	return false
}

func main() {
	http.Handle(FACEBOOK_AUTH_CALLBACK_ROUTE, handleFacebookAuth())
	http.Handle("/auth/login", promptFacebookLogin())
	http.Handle("/auth/logout", handleLogout())

	FILES_PREFIX := "/files/"
	http.Handle(FILES_PREFIX, requireAuth(handleFiles(FILES_PREFIX)))

	http.Handle("/", serveString(""))

	err := http.ListenAndServe(":"+strconv.Itoa(CONFIG.InternalPort), context.ClearHandler(http.DefaultServeMux))
	if err != nil {
		panic(err)
	}
}

const CONTENTS = `

Message: [[[MESSAGE]]]

Logged in? [[[LOGGED IN]]]

login

logout

files

`
<commit_msg>prefer properly versioned endpoint<commit_after>package main

import (
	"encoding/json"
	"errors"
	"flag"
	"github.com/gorilla/context"
	"github.com/gorilla/sessions"
	"golang.org/x/oauth2"
	"golang.org/x/oauth2/facebook"
	"log"
	"net/http"
	"os"
	"strconv"
	"strings"
)

type FbrpConfig struct {
	AppId         string `json:"app_id"`
	AppSecret     string `json:"app_secret"`
	Hostname      string `json:"hostname"`
	SecretGroupId string `json:"secret_group_id"`
	ServeRoot     string `json:"serve_root"`
	InternalPort  int    `json:"internal_port"`
	SessionSecret string `json:"session_secret"`
}

var CONFIG FbrpConfig

var store *sessions.CookieStore
var SESSION_NAME = "session-name"
var COOKIE_HAS_AUTH = "hasAuth"

var FACEBOOK_OAUTH_CONFIG oauth2.Config
var FACEBOOK_AUTH_CALLBACK_ROUTE = "/auth/login/facebook/callback"

func init() {
	var configFile = flag.String("config", "./fbrp.config", "config file location")
	flag.Parse()
	log.Println("reading config from:", *configFile)
	file, err := os.Open(*configFile)
	if err != nil {
		panic(err)
	}
	decoder := json.NewDecoder(file)
	decoder.Decode(&CONFIG)

	log.Println(CONFIG)

	if CONFIG.SessionSecret == "" {
		panic("SessionSecret should never be empty")
	}
	store = sessions.NewCookieStore([]byte(CONFIG.SessionSecret))

	FACEBOOK_OAUTH_CONFIG = oauth2.Config{
		ClientID:     CONFIG.AppId,
		ClientSecret: CONFIG.AppSecret,
		RedirectURL:  "http://" + CONFIG.Hostname + FACEBOOK_AUTH_CALLBACK_ROUTE,
		Scopes:       []string{"user_about_me,user_groups"},
		Endpoint:     facebook.Endpoint,
	}
}

func handleFiles(prefix string) http.Handler {
	fs := http.FileServer(http.Dir(CONFIG.ServeRoot))
	return http.StripPrefix(prefix, fs)
}

func requireAuth(innerHandler http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		session, _ := store.Get(r, SESSION_NAME)
		v, ok := session.Values[COOKIE_HAS_AUTH]
		if ok && v.(bool) {
			innerHandler.ServeHTTP(w, r)
		} else {
			w.WriteHeader(403)
			serveString("You're not logged in, login first").ServeHTTP(w, r)
		}
	})
}

func promptFacebookLogin() http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		facebookLoginUrl := FACEBOOK_OAUTH_CONFIG.AuthCodeURL("login")
		http.Redirect(w, r, facebookLoginUrl, 301)
	})
}

func checkFacebookGroups(token *oauth2.Token) (bool, error) {
	client := FACEBOOK_OAUTH_CONFIG.Client(oauth2.NoContext, token)
	resp, err := client.Get("https://graph.facebook.com/v2.3/me?fields=id,name,groups{id}")
	if err != nil {
		log.Println("failed to check groups")
		log.Println(err)
		return false, err
	}
	defer resp.Body.Close()

	var respData map[string]interface{}

	_ = json.NewDecoder(resp.Body).Decode(&respData)

	name := respData["name"].(string)
	listOfGroups := respData["groups"].(map[string]interface{})
	listOfGroups2 := listOfGroups["data"].([]interface{})

	for _, group := range listOfGroups2 {
		groupId := group.(map[string]interface{})["id"].(string)
		if groupId == CONFIG.SecretGroupId {
			log.Println("LOGIN: ", name)
			return true, nil
		}
	}
	return false, errors.New("You don't belong to the secret group, sorry!")
}

func handleFacebookAuth() http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		code := r.FormValue("code")
		token, _ := FACEBOOK_OAUTH_CONFIG.Exchange(oauth2.NoContext, code)

		userAllowed, err := checkFacebookGroups(token)
		if err != nil {
			serveString("something bad happened: "+err.Error()).ServeHTTP(w, r)
		}

		if userAllowed {
			login(w, r)
		} else {
			logout(w, r)
		}

		http.Redirect(w, r, "/", 301)
	})
}

func handleLogout() http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		logout(w, r)
		http.Redirect(w, r, "/", 301)
	})
}

func serveString(message string) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		isLoggedInStr := "yes!"
		if !isLoggedIn(r) {
			isLoggedInStr = "No!"
		}
		contents := strings.Replace(CONTENTS, "[[[LOGGED IN]]]", isLoggedInStr, 1)
		contents = strings.Replace(contents, "[[[MESSAGE]]]", message, 1)
		w.Write([]byte(contents))
	})
}

func login(w http.ResponseWriter, r *http.Request) {
	session, _ := store.Get(r, SESSION_NAME)
	session.Values[COOKIE_HAS_AUTH] = true
	session.Save(r, w)
}

func logout(w http.ResponseWriter, r *http.Request) {
	session, _ := store.Get(r, SESSION_NAME)
	session.Values[COOKIE_HAS_AUTH] = false
	session.Save(r, w)
}

func isLoggedIn(r *http.Request) bool {
	session, _ := store.Get(r, SESSION_NAME)
	authd, ok := session.Values[COOKIE_HAS_AUTH]
	if ok && authd.(bool) {
		return true
	}
	return false
}

func main() {
	http.Handle(FACEBOOK_AUTH_CALLBACK_ROUTE, handleFacebookAuth())
	http.Handle("/auth/login", promptFacebookLogin())
	http.Handle("/auth/logout", handleLogout())

	FILES_PREFIX := "/files/"
	http.Handle(FILES_PREFIX, requireAuth(handleFiles(FILES_PREFIX)))

	http.Handle("/", serveString(""))

	err := http.ListenAndServe(":"+strconv.Itoa(CONFIG.InternalPort), context.ClearHandler(http.DefaultServeMux))
	if err != nil {
		panic(err)
	}
}

const CONTENTS = `

Message: [[[MESSAGE]]]

Logged in? [[[LOGGED IN]]]

login

logout

files

`
<|endoftext|>


<commit_before>package main

import (
	"log"
	"os"
	"github.com/hsjunnesson/top-five/Godeps/_workspace/src/github.com/gin-gonic/gin"
)

func main() {
	port := os.Getenv("PORT")

	if port == "" {
		log.Fatal("$PORT must be set")
	}

	app := gin.Default()
	app.GET("/lists", ListsList)
	app.GET("/lists/:list_id", ListsDetail)

	app.Static("/public", "./public")
	app.Static("/1726D19535E7EF78AD05045709BA5EA1.txt", "./public/1726D19535E7EF78AD05045709BA5EA1.txt")

	app.Run(":" + port)

}

<commit_msg>Static file.<commit_after>package main

import (
	"log"
	"os"
	"github.com/hsjunnesson/top-five/Godeps/_workspace/src/github.com/gin-gonic/gin"
)

func main() {
	port := os.Getenv("PORT")

	if port == "" {
		log.Fatal("$PORT must be set")
	}

	app := gin.Default()

	app.Static("/", "public")
	app.GET("/lists", ListsList)
	app.GET("/lists/:list_id", ListsDetail)

	app.Run(":" + port)

}

<|endoftext|>


<commit_before>package main

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

func longUsage() {
	fmt.Println(`NAME
	buildo -- build your go binaries

USAGE
	buildo [flags] <ALL|target,...> [ALL|platform,...]

DESCRIPTION
	tbd

FLAGS
	--list
		list available targets and os/arch combinations
	--output=<location/file>
		location to place the built binaries / compressed file
		default: ./$PWD_bin | ./$PWD_bin.tgz
	--tgz
		whether or not to make a gzipped tar out of built binaries
		default: false
	--debug
		output debug information
		default: false
	--help
		display help info

EXAMPLES
(Assuming $PWD of /home/user/go/src/myproj)
	$ buildo
		builds the default binary for the current platform and places it in
		myproj/myproj_bin
	$ buildo ALL
		builds all binaries for current platform and places them in myproj/myproj_bin
	$ buildo --gz foo,bar windows_386,linux_386
		builds foo and bar binaries and gzips them into myproj/myproj_bin.tgz
`)
	os.Exit(1)
}

var outputLoc string
var doList bool
var toZip bool
var debugOut bool
var cwd, _ = os.Getwd()

func main() {
	flag.Usage = longUsage
	flag.BoolVar(&doList, "list", false, "")
	flag.BoolVar(&toZip, "tgz", false, "")
	flag.BoolVar(&debugOut, "debug", false, "")
	flag.StringVar(&outputLoc, "output", "", "")
	flag.Parse()

	targets := getTargets()
	architectures := getArchitectures()

	if doList {
		if flag.NFlag() > 1 {
			fatal("--list can't be combined with other flags")
			longUsage()
		}

		sortedTargets := make([]string, 0, len(targets))
		for targetName, _ := range targets {
			//TODO: Default check
			sortedTargets = append(sortedTargets, targetName)
		}
		sort.Strings(sortedTargets)
		fmt.Println("Available targets:")
		for _, targetName := range sortedTargets {
			fmt.Printf("\t%s", targetName)
			if targets[targetName] == cwd || len(targets) == 1 {
				fmt.Println(" *")
			} else {
				fmt.Println()
			}
		}

		sortedArchitectures := make([]string, 0, len(architectures))
		for archName, _ := range architectures {
			sortedArchitectures = append(sortedArchitectures, archName)
		}
		sort.Strings(sortedArchitectures)
		fmt.Println("Available architectures:")
		for _, archName := range sortedArchitectures {
			fmt.Printf("\t%s", archName)
			if architectures[archName].Native {
				fmt.Println(" *")
			} else {
				fmt.Println("")
			}
		}
	}
}
<commit_msg>allow --debug with --list<commit_after>package main

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

func longUsage() {
	fmt.Println(`NAME
	buildo -- build your go binaries

USAGE
	buildo [flags] <ALL|target,...> [ALL|platform,...]

DESCRIPTION
	tbd

FLAGS
	--list
		list available targets and os/arch combinations
	--output=<location/file>
		location to place the built binaries / compressed file
		default: ./$PWD_bin | ./$PWD_bin.tgz
	--tgz
		whether or not to make a gzipped tar out of built binaries
		default: false
	--debug
		output debug information
		default: false
	--help
		display help info

EXAMPLES
(Assuming $PWD of /home/user/go/src/myproj)
	$ buildo
		builds the default binary for the current platform and places it in
		myproj/myproj_bin
	$ buildo ALL
		builds all binaries for current platform and places them in myproj/myproj_bin
	$ buildo --gz foo,bar windows_386,linux_386
		builds foo and bar binaries and gzips them into myproj/myproj_bin.tgz
`)
	os.Exit(1)
}

var outputLoc string
var doList bool
var toZip bool
var debugOut bool
var cwd, _ = os.Getwd()

func main() {
	flag.Usage = longUsage
	flag.BoolVar(&doList, "list", false, "")
	flag.BoolVar(&toZip, "tgz", false, "")
	flag.BoolVar(&debugOut, "debug", false, "")
	flag.StringVar(&outputLoc, "output", "", "")
	flag.Parse()

	targets := getTargets()
	architectures := getArchitectures()

	if doList {
		if flag.NFlag() >= 2 && !debugOut {
			fatal("--list can only be combined with --debug")
			longUsage()
		}

		sortedTargets := make([]string, 0, len(targets))
		for targetName, _ := range targets {
			//TODO: Default check
			sortedTargets = append(sortedTargets, targetName)
		}
		sort.Strings(sortedTargets)
		fmt.Println("Available targets:")
		for _, targetName := range sortedTargets {
			fmt.Printf("\t%s", targetName)
			if targets[targetName] == cwd || len(targets) == 1 {
				fmt.Println(" *")
			} else {
				fmt.Println()
			}
		}

		sortedArchitectures := make([]string, 0, len(architectures))
		for archName, _ := range architectures {
			sortedArchitectures = append(sortedArchitectures, archName)
		}
		sort.Strings(sortedArchitectures)
		fmt.Println("Available architectures:")
		for _, archName := range sortedArchitectures {
			fmt.Printf("\t%s", archName)
			if architectures[archName].Native {
				fmt.Println(" *")
			} else {
				fmt.Println("")
			}
		}
	}
}
<|endoftext|>