Exemple #1
0
func replCLI(env *Env) {
	defer fmt.Println("\nbye!")
	counter := readline.HistorySize()
	for {
		buf := bytes.Buffer{}
		prompt := fmt.Sprintf("[%d]-> ", counter)
		for {
			l, err := readline.String(prompt)
			if err == io.EOF {
				return
			}
			buf.WriteString(l)
			if validSexp(buf.String()) {
				break
			}
			buf.WriteString("\n")
			prompt = ": "
		}
		result, err := repl(buf.String(), env)
		if err != nil && err != ErrorEOF {
			fmt.Println("Error:", err)
		} else {
			fmt.Println(result)
		}
		readline.AddHistory(buf.String())
		counter++

	}
}
Exemple #2
0
func main() {
	var err error
	defer func() {
		if e := recover(); e != nil {
			fmt.Fprintf(os.Stderr, "FATAL: %v\n", e)
		}
	}()
	homedir := client.FindHomedir()
	// command line options
	var config = flag.String("c", homedir+"/.migrc", "Load configuration from file")
	var quiet = flag.Bool("q", false, "don't display banners and prompts")
	var showversion = flag.Bool("V", false, "show build version and exit")
	flag.Parse()

	if *showversion {
		fmt.Println(version)
		os.Exit(0)
	}

	// silence extra output
	out := os.Stdout
	if *quiet {
		out.Close()
		out, err = os.Open(os.DevNull)
		if err != nil {
			panic(err)
		}
	}
	defer out.Close()

	fmt.Fprintf(out, "\x1b[32;1m"+banner+"\x1b[0m")

	// append a space after completion
	readline.CompletionAppendChar = 0x20
	// load history
	historyfile := homedir + "/.mig_history"
	fi, err := os.Stat(historyfile)
	if err == nil && fi.Size() > 0 {
		err = readline.LoadHistory(historyfile)
		if err != nil {
			fmt.Fprintf(os.Stderr, "failed to load history from %s\n", historyfile)
		}
	}
	// instanciate an API client
	conf, err := client.ReadConfiguration(*config)
	if err != nil {
		panic(err)
	}
	cli, err := client.NewClient(conf, "console-"+version)
	if err != nil {
		panic(err)
	}
	// print platform status
	err = printStatus(cli)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Fprintf(out, "\nConnected to %s. Exit with \x1b[32;1mctrl+d\x1b[0m. Type \x1b[32;1mhelp\x1b[0m for help.\n", cli.Conf.API.URL)
	for {
		// completion
		var symbols = []string{"action", "agent", "create", "command", "help", "history",
			"exit", "showcfg", "status", "investigator", "search", "where", "and"}
		readline.Completer = func(query, ctx string) []string {
			var res []string
			for _, sym := range symbols {
				if strings.HasPrefix(sym, query) {
					res = append(res, sym)
				}
			}
			return res
		}

		input, err := readline.String("\x1b[32;1mmig>\x1b[0m ")
		if err == io.EOF {
			break
		}
		if err != nil {
			fmt.Println("error: ", err)
			break
		}
		orders := strings.Split(strings.TrimSpace(input), " ")
		switch orders[0] {
		case "action":
			if len(orders) == 2 {
				err = actionReader(input, cli)
				if err != nil {
					log.Println(err)
				}
			} else {
				fmt.Println("error: missing action id in 'action <id>'")
			}
		case "agent":
			err = agentReader(input, cli)
			if err != nil {
				log.Println(err)
			}
		case "create":
			if len(orders) == 2 {
				switch orders[1] {
				case "action":
					var a mig.Action
					err = actionLauncher(a, cli)
				case "investigator":
					err = investigatorCreator(cli)
				default:
					fmt.Printf("unknown order 'create %s'\n", orders[1])
				}
				if err != nil {
					log.Println(err)
				}
			} else {
				fmt.Println("error: missing order, must be 'create <action|investigator>'")
			}
		case "command":
			err = commandReader(input, cli)
			if err != nil {
				log.Println(err)
			}
		case "exit":
			fmt.Printf("exit\n")
			goto exit
		case "help":
			fmt.Printf(`The following orders are available:
action <id>		enter interactive action reader mode for action <id>
agent <id>		enter interactive agent reader mode for agent <id>
create action		create a new action
create investigator	create a new investigator, will prompt for name and public key
command <id>		enter command reader mode for command <id>
exit			leave
help			show this help
history <count>		print last <count> entries in history. count=10 by default.
investigator <id>	enter interactive investigator management mode for investigator <id>
search			perform a search. see "search help" for more information.
showcfg			display running configuration
status			display platform status: connected agents, latest actions, ...
`)
		case "history":
			var count int64 = 10
			if len(orders) > 1 {
				count, err = strconv.ParseInt(orders[1], 10, 64)
				if err != nil {
					log.Println(err)
					break
				}
			}
			for i := readline.HistorySize(); i > 0 && count > 0; i, count = i-1, count-1 {
				fmt.Println(readline.GetHistory(i - 1))
			}
		case "investigator":
			err = investigatorReader(input, cli)
			if err != nil {
				log.Println(err)
			}
		case "search":
			err = search(input, cli)
			if err != nil {
				log.Println(err)
			}
		case "showcfg":
			fmt.Printf("homedir = %s\n[api]\n    url = %s\n[gpg]\n    home = %s\n    keyid = %s\n",
				cli.Conf.API.URL, cli.Conf.Homedir, cli.Conf.GPG.Home, cli.Conf.GPG.KeyID)
		case "status":
			err = printStatus(cli)
			if err != nil {
				log.Println(err)
			}
		case "":
			break
		default:
			fmt.Printf("Unknown order '%s'\n", orders[0])
		}
		readline.AddHistory(input)
	}
exit:
	fmt.Fprintf(out, footer)
	err = readline.SaveHistory(historyfile)
	if err != nil {
		fmt.Fprintf(os.Stderr, "failed to save history to %s\n", historyfile)
	}
}