Exemple #1
0
Fichier : cli.go Projet : stef/pond
func (c *cliClient) Start() {
	oldState, err := terminal.MakeRaw(0)
	if err != nil {
		panic(err.Error())
	}
	defer terminal.Restore(0, oldState)

	signal.Notify(make(chan os.Signal), os.Interrupt)

	wrapper, interruptChan := NewTerminalWrapper(os.Stdin)
	wrapper.SetErrorOnInterrupt(true)
	c.interrupt = interruptChan
	c.termWrapper = wrapper

	c.term = terminal.NewTerminal(wrapper, "> ")
	if width, height, err := terminal.GetSize(0); err == nil {
		c.term.SetSize(width, height)
	}

	c.loadUI()

	if c.writerChan != nil {
		c.save()
	}
	if c.writerChan != nil {
		close(c.writerChan)
		<-c.writerDone
	}
	if c.fetchNowChan != nil {
		close(c.fetchNowChan)
	}
	if c.stateLock != nil {
		c.stateLock.Close()
	}
}
Exemple #2
0
// Close cleans up mongod and mongo processes and closes fd for the terminal
func (sh *QShell) Close() error {
	closeErr := sh.mongoStateHolder.close()
	if err := terminal.Restore(sh.stdinFd, sh.oldState); err != nil && closeErr == nil {
		closeErr = err
	}
	return closeErr
}
Exemple #3
0
// Start raw acts as Start but put the terminal into raw mode. Returns an
// additional function that should be used to restore the terminal state.
func StartRaw(c *exec.Cmd) (pty *os.File, restore func(), err error) {
	pty, err = Start(c)
	oldState, err := terminal.MakeRaw(int(pty.Fd()))
	if err != nil {
		return nil, nil, err
	}

	return pty, func() {
		_ = terminal.Restore(int(pty.Fd()), oldState)
	}, nil
}
func getch() byte {
	if oldState, err := terminal.MakeRaw(0); err != nil {
		panic(err)
	} else {
		defer terminal.Restore(0, oldState)
	}

	var buf [1]byte
	if n, err := syscall.Read(0, buf[:]); n == 0 || err != nil {
		panic(err)
	}
	return buf[0]
}
Exemple #5
0
// makeSession initializes a gossh.Session connected to the invoking process's stdout/stderr/stdout.
// If the invoking session is a terminal, a TTY will be requested for the SSH session.
// It returns a gossh.Session, a finalizing function used to clean up after the session terminates,
// and any error encountered in setting up the session.
func makeSession(client *SSHForwardingClient) (session *gossh.Session, finalize func(), err error) {
	session, err = client.NewSession()
	if err != nil {
		return
	}
	if err = client.ForwardAgentAuthentication(session); err != nil {
		return
	}

	session.Stdout = os.Stdout
	session.Stderr = os.Stderr
	session.Stdin = os.Stdin

	modes := gossh.TerminalModes{
		gossh.ECHO:          1,     // enable echoing
		gossh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
		gossh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud
	}

	fd := int(os.Stdin.Fd())
	if terminal.IsTerminal(fd) {

		var termWidth, termHeight int
		var oldState *terminal.State

		oldState, err = terminal.MakeRaw(fd)
		if err != nil {
			return
		}

		finalize = func() {
			session.Close()
			terminal.Restore(fd, oldState)
		}

		termWidth, termHeight, err = terminal.GetSize(fd)

		if err != nil {
			return
		}
		err = session.RequestPty("xterm-256color", termHeight, termWidth, modes)
	} else {
		finalize = func() {
			session.Close()
		}
	}

	return
}
Exemple #6
0
func main() {
	w := eval.NewWorld()
	w.DefineVar("connect", eval.NewFuncType([]eval.Type{}, false, []eval.Type{}), &funcV{&testFunc{}})

	fmt.Println(":: welcome to go-eval...\n(hit ^D to exit)")

	fd := int(os.Stdin.Fd())
	oldState, err := terminal.MakeRaw(fd)
	if err != nil {
		panic(err)
	}
	defer terminal.Restore(fd, oldState)
	term := terminal.NewTerminal(&shell{r: os.Stdin, w: os.Stdout}, "> ")
	if term == nil {
		panic(errors.New("could not create terminal"))
	}

	for {
		line, err := term.ReadLine()
		if err != nil {
			break
		}
		code, err := w.Compile(fset, line)
		if err != nil {
			term.Write([]byte(err.Error() + "\n"))
			continue
		}
		v, err := code.Run()
		if err != nil {
			term.Write([]byte(err.Error() + "\n"))
			continue
		}
		if v != nil {
			term.Write([]byte(v.String() + "\n"))
		}
	}
}
Exemple #7
0
func (c *attachCmd) run(args []string) error {
	name := "foo"
	if len(args) > 1 {
		return errArgs
	}
	if len(args) == 1 {
		name = args[0]
	}
	config, err := flex.LoadConfig()
	if err != nil {
		return err
	}

	// NewClient will ping the server to test the connection before returning.
	d, err := flex.NewClient(config)
	if err != nil {
		return err
	}

	// TODO - random value in place of 5 :)
	secret := "5"

	l, err := d.Attach(name, "/bin/bash", secret)
	if err != nil {
		return err
	}

	cfd := syscall.Stdout
	if terminal.IsTerminal(cfd) {
		oldttystate, err := terminal.MakeRaw(cfd)
		if err != nil {
			return err
		}
		defer terminal.Restore(cfd, oldttystate)
	}

	// open a connection to l and connect stdin/stdout to it

	// connect
	conn, err := net.Dial("tcp", l)
	if err != nil {
		return err
	}
	_, err = conn.Write([]byte(secret))
	if err != nil {
		return err
	}

	go func() {
		_, err := io.Copy(conn, os.Stdin)
		if err != nil {
			fmt.Println("Stdin read error: %s", err.Error())
			return
		}
	}()
	_, err = io.Copy(os.Stdout, conn)
	if err != nil {
		fmt.Println("Connection read error: %s", err.Error())
		return err
	}

	return nil
}
Exemple #8
0
func main() {
	flag.Parse()
	if flag.NArg() > 0 {
		cons = flag.Arg(0)
	} else {
		log.Fatal("Must give a console name as the last argument.")
	}

	state, err := terminal.MakeRaw(int(os.Stdin.Fd()))
	if err != nil {
		log.Fatal("MakeRaw: ", err)
	}

	// put it back the way we found it when we exit
	defer func() {
		_ = terminal.Restore(int(os.Stdin.Fd()), state)
		// clean up cursor position
		fmt.Print("\r")
	}()

	c, err := net.Dial("tcp", "localhost:1234")
	if err != nil {
		log.Print("Could not connect: ", err)
		return
	}
	enc := gob.NewEncoder(c)

	req := new(connReq)
	req.Cmd = Listen
	req.Name = cons
	err = enc.Encode(req)
	if err != nil {
		log.Print("Could not write request: ", err)
		return
	}
	take(enc, Take)

	go readinput(c, enc)

	dec := gob.NewDecoder(c)
	reply := new(connReply)
L:
	for {
		err := dec.Decode(reply)
		if err != nil {
			if err != io.EOF {
				log.Print("recv error: ", err)
			}
			break
		}

		debug("Reply code: ", reply.Code)
		switch reply.Code {
		default:
			log.Print("Bad reply from server: ", reply.Code, "\r")
			break
		case Ok:
			// nothing
		case ReadOnly:
			fmt.Fprintf(os.Stdout, " [read-only] ")
			readwrite = false
		case ReadWrite:
			fmt.Fprintf(os.Stdout, " [read-write] ")
			readwrite = true
		case Err:
			log.Print("Error from server: ", reply.Err, "\r")
			break L
		case Data:
			os.Stdout.Write(reply.Data[:])
		}
	}
	log.Print("Disconnecting.\r")
	c.Close()
}
Exemple #9
0
func (u *uterm) Restore() {
	terminal.Restore(0, u.s)
}
Exemple #10
0
func main() {
	flag.Parse()

	oldState, err := terminal.MakeRaw(0)
	if err != nil {
		panic(err.Error())
	}
	defer terminal.Restore(0, oldState)
	term := terminal.NewTerminal(os.Stdin, "> ")
	updateTerminalSize(term)

	resizeChan := make(chan os.Signal)
	go func() {
		for _ = range resizeChan {
			updateTerminalSize(term)
		}
	}()
	signal.Notify(resizeChan, syscall.SIGWINCH)

	if len(*configFile) == 0 {
		homeDir := os.Getenv("HOME")
		if len(homeDir) == 0 {
			alert(term, "$HOME not set. Please either export $HOME or use the -config-file option.\n")
			return
		}
		persistentDir := filepath.Join(homeDir, "Persistent")
		if stat, err := os.Lstat(persistentDir); err == nil && stat.IsDir() {
			// Looks like Tails.
			homeDir = persistentDir
		}
		*configFile = filepath.Join(homeDir, ".xmpp-client")
	}

	config, err := ParseConfig(*configFile)
	if err != nil {
		alert(term, "Failed to parse config file: "+err.Error())
		config = new(Config)
		if !enroll(config, term) {
			return
		}
		config.filename = *configFile
		config.Save()
	}

	password := config.Password
	if len(password) == 0 {
		if password, err = term.ReadPassword(fmt.Sprintf("Password for %s (will not be saved to disk): ", config.Account)); err != nil {
			alert(term, "Failed to read password: "******"@", 2)
	if len(parts) != 2 {
		alert(term, "invalid username (want user@domain): "+config.Account)
		return
	}
	user := parts[0]
	domain := parts[1]

	var addr string
	addrTrusted := false

	if len(config.Server) > 0 && config.Port > 0 {
		addr = fmt.Sprintf("%s:%d", config.Server, config.Port)
		addrTrusted = true
	} else {
		if len(config.Proxies) > 0 {
			alert(term, "Cannot connect via a proxy without Server and Port being set in the config file as an SRV lookup would leak information.")
			return
		}
		host, port, err := xmpp.Resolve(domain)
		if err != nil {
			alert(term, "Failed to resolve XMPP server: "+err.Error())
			return
		}
		addr = fmt.Sprintf("%s:%d", host, port)
	}

	var dialer proxy.Dialer
	for i := len(config.Proxies) - 1; i >= 0; i-- {
		u, err := url.Parse(config.Proxies[i])
		if err != nil {
			alert(term, "Failed to parse "+config.Proxies[i]+" as a URL: "+err.Error())
			return
		}
		if dialer == nil {
			dialer = proxy.Direct
		}
		if dialer, err = proxy.FromURL(u, dialer); err != nil {
			alert(term, "Failed to parse "+config.Proxies[i]+" as a proxy: "+err.Error())
			return
		}
	}

	var certSHA256 []byte
	if len(config.ServerCertificateSHA256) > 0 {
		certSHA256, err = hex.DecodeString(config.ServerCertificateSHA256)
		if err != nil {
			alert(term, "Failed to parse ServerCertificateSHA256 (should be hex string): "+err.Error())
			return
		}
		if len(certSHA256) != 32 {
			alert(term, "ServerCertificateSHA256 is not 32 bytes long")
			return
		}
	}
	xmppConfig := &xmpp.Config{
		Log:                     &lineLogger{term, nil},
		Create:                  *createAccount,
		TrustedAddress:          addrTrusted,
		Archive:                 false,
		ServerCertificateSHA256: certSHA256,
	}

	if len(config.RawLogFile) > 0 {
		rawLog, err := os.OpenFile(config.RawLogFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
		if err != nil {
			alert(term, "Failed to open raw log file: "+err.Error())
			return
		}

		lock := new(sync.Mutex)
		in := rawLogger{
			out:    rawLog,
			prefix: []byte("<- "),
			lock:   lock,
		}
		out := rawLogger{
			out:    rawLog,
			prefix: []byte("-> "),
			lock:   lock,
		}
		in.other, out.other = &out, &in

		xmppConfig.InLog = &in
		xmppConfig.OutLog = &out

		defer in.flush()
		defer out.flush()
	}

	if dialer != nil {
		info(term, "Making connection to "+addr+" via proxy")
		if xmppConfig.Conn, err = dialer.Dial("tcp", addr); err != nil {
			alert(term, "Failed to connect via proxy: "+err.Error())
			return
		}
	}

	conn, err := xmpp.Dial(addr, user, domain, password, xmppConfig)
	if err != nil {
		alert(term, "Failed to connect to XMPP server: "+err.Error())
		return
	}

	s := Session{
		account:           config.Account,
		conn:              conn,
		term:              term,
		conversations:     make(map[string]*otr.Conversation),
		knownStates:       make(map[string]string),
		privateKey:        new(otr.PrivateKey),
		config:            config,
		pendingRosterChan: make(chan *rosterEdit),
		pendingSubscribes: make(map[string]string),
		lastActionTime:    time.Now(),
	}
	info(term, "Fetching roster")

	//var rosterReply chan xmpp.Stanza
	rosterReply, _, err := s.conn.RequestRoster()
	if err != nil {
		alert(term, "Failed to request roster: "+err.Error())
		return
	}

	conn.SignalPresence("")

	s.input = Input{
		term:        term,
		uidComplete: new(priorityList),
	}
	commandChan := make(chan interface{})
	go s.input.ProcessCommands(commandChan)

	stanzaChan := make(chan xmpp.Stanza)
	go s.readMessages(stanzaChan)

	s.privateKey.Parse(config.PrivateKey)
	s.timeouts = make(map[xmpp.Cookie]time.Time)

	info(term, fmt.Sprintf("Your fingerprint is %x", s.privateKey.Fingerprint()))

	ticker := time.NewTicker(1 * time.Second)

MainLoop:
	for {
		select {
		case now := <-ticker.C:
			haveExpired := false
			for _, expiry := range s.timeouts {
				if now.After(expiry) {
					haveExpired = true
					break
				}
			}
			if !haveExpired {
				continue
			}

			newTimeouts := make(map[xmpp.Cookie]time.Time)
			for cookie, expiry := range s.timeouts {
				if now.After(expiry) {
					s.conn.Cancel(cookie)
				} else {
					newTimeouts[cookie] = expiry
				}
			}
			s.timeouts = newTimeouts

		case edit := <-s.pendingRosterChan:
			if !edit.isComplete {
				info(s.term, "Please edit "+edit.fileName+" and run /rostereditdone when complete")
				s.pendingRosterEdit = edit
				continue
			}
			if s.processEditedRoster(edit) {
				s.pendingRosterEdit = nil
			} else {
				alert(s.term, "Please reedit file and run /rostereditdone again")
			}

		case rosterStanza, ok := <-rosterReply:
			if !ok {
				alert(s.term, "Failed to read roster: "+err.Error())
				return
			}
			if s.roster, err = xmpp.ParseRoster(rosterStanza); err != nil {
				alert(s.term, "Failed to parse roster: "+err.Error())
				return
			}
			for _, entry := range s.roster {
				s.input.AddUser(entry.Jid)
			}
			info(s.term, "Roster received")

		case cmd, ok := <-commandChan:
			if !ok {
				warn(term, "Exiting because command channel closed")
				break MainLoop
			}
			s.lastActionTime = time.Now()
			switch cmd := cmd.(type) {
			case quitCommand:
				for to, conversation := range s.conversations {
					msgs := conversation.End()
					for _, msg := range msgs {
						s.conn.Send(to, string(msg))
					}
				}
				break MainLoop
			case versionCommand:
				replyChan, cookie, err := s.conn.SendIQ(cmd.User, "get", xmpp.VersionQuery{})
				if err != nil {
					alert(s.term, "Error sending version request: "+err.Error())
					continue
				}
				s.timeouts[cookie] = time.Now().Add(5 * time.Second)
				go s.awaitVersionReply(replyChan, cmd.User)
			case rosterCommand:
				info(s.term, "Current roster:")
				maxLen := 0
				for _, item := range s.roster {
					if maxLen < len(item.Jid) {
						maxLen = len(item.Jid)
					}
				}

				for _, item := range s.roster {
					state, ok := s.knownStates[item.Jid]

					line := ""
					if ok {
						line += "[*] "
					} else if cmd.OnlineOnly {
						continue
					} else {
						line += "[ ] "
					}

					line += item.Jid
					numSpaces := 1 + (maxLen - len(item.Jid))
					for i := 0; i < numSpaces; i++ {
						line += " "
					}
					line += item.Subscription + "\t" + item.Name
					if ok {
						line += "\t" + state
					}
					info(s.term, line)
				}
			case rosterEditCommand:
				if s.pendingRosterEdit != nil {
					warn(s.term, "Aborting previous roster edit")
					s.pendingRosterEdit = nil
				}
				rosterCopy := make([]xmpp.RosterEntry, len(s.roster))
				copy(rosterCopy, s.roster)
				go s.editRoster(rosterCopy)
			case rosterEditDoneCommand:
				if s.pendingRosterEdit == nil {
					warn(s.term, "No roster edit in progress. Use /rosteredit to start one")
					continue
				}
				go s.loadEditedRoster(*s.pendingRosterEdit)
			case toggleStatusUpdatesCommand:
				s.config.HideStatusUpdates = !s.config.HideStatusUpdates
				s.config.Save()
				// Tell the user the current state of the statuses
				if s.config.HideStatusUpdates {
					info(s.term, "Status updated disabled")
				} else {
					info(s.term, "Status updates enabled")
				}
			case confirmCommand:
				s.handleConfirmOrDeny(cmd.User, true /* confirm */)
			case denyCommand:
				s.handleConfirmOrDeny(cmd.User, false /* deny */)
			case addCommand:
				s.conn.SendPresence(cmd.User, "subscribe", "" /* generate id */)
			case msgCommand:
				conversation, ok := s.conversations[cmd.to]
				if (!ok || !conversation.IsEncrypted()) && config.ShouldEncryptTo(cmd.to) {
					warn(s.term, fmt.Sprintf("Did not send: no encryption established with %s", cmd.to))
					continue
				}
				var msgs [][]byte
				message := []byte(cmd.msg)
				// Automatically tag all outgoing plaintext
				// messages with a whitespace tag that
				// indicates that we support OTR.
				if config.OTRAutoAppendTag &&
					!bytes.Contains(message, []byte("?OTR")) &&
					(!ok || !conversation.IsEncrypted()) {
					message = append(message, OTRWhitespaceTag...)
				}
				if ok {
					var err error
					msgs, err = conversation.Send(message)
					if err != nil {
						alert(s.term, err.Error())
						break
					}
				} else {
					msgs = [][]byte{[]byte(message)}
				}
				for _, message := range msgs {
					s.conn.Send(cmd.to, string(message))
				}
			case otrCommand:
				s.conn.Send(string(cmd.User), otr.QueryMessage)
			case otrInfoCommand:
				info(term, fmt.Sprintf("Your OTR fingerprint is %x", s.privateKey.Fingerprint()))
				for to, conversation := range s.conversations {
					if conversation.IsEncrypted() {
						info(s.term, fmt.Sprintf("Secure session with %s underway:", to))
						printConversationInfo(s, to, conversation)
					}
				}
			case endOTRCommand:
				to := string(cmd.User)
				conversation, ok := s.conversations[to]
				if !ok {
					alert(s.term, "No secure session established")
					break
				}
				msgs := conversation.End()
				for _, msg := range msgs {
					s.conn.Send(to, string(msg))
				}
			case authQACommand:
				to := string(cmd.User)
				conversation, ok := s.conversations[to]
				if !ok {
					alert(s.term, "Can't authenticate without a secure conversation established")
					break
				}
				msgs, err := conversation.Authenticate(cmd.Question, []byte(cmd.Secret))
				if err != nil {
					alert(s.term, "Error while starting authentication with "+to+": "+err.Error())
				}
				for _, msg := range msgs {
					s.conn.Send(to, string(msg))
				}
			case authOobCommand:
				fpr, err := hex.DecodeString(cmd.Fingerprint)
				if err != nil {
					alert(s.term, fmt.Sprintf("Invalid fingerprint %s - not authenticated", cmd.Fingerprint))
					break
				}
				existing := s.config.UserIdForFingerprint(fpr)
				if len(existing) != 0 {
					alert(s.term, fmt.Sprintf("Fingerprint %s already belongs to %s", cmd.Fingerprint, existing))
					break
				}
				s.config.KnownFingerprints = append(s.config.KnownFingerprints, KnownFingerprint{fingerprint: fpr, UserId: cmd.User})
				s.config.Save()
				info(s.term, fmt.Sprintf("Saved manually verified fingerprint %s for %s", cmd.Fingerprint, cmd.User))
			case awayCommand:
				s.conn.SignalPresence("away")
			case chatCommand:
				s.conn.SignalPresence("chat")
			case dndCommand:
				s.conn.SignalPresence("dnd")
			case xaCommand:
				s.conn.SignalPresence("xa")
			case onlineCommand:
				s.conn.SignalPresence("")
			}
		case rawStanza, ok := <-stanzaChan:
			if !ok {
				warn(term, "Exiting because channel to server closed")
				break MainLoop
			}
			switch stanza := rawStanza.Value.(type) {
			case *xmpp.ClientMessage:
				s.processClientMessage(stanza)
			case *xmpp.ClientPresence:
				s.processPresence(stanza)
			case *xmpp.ClientIQ:
				if stanza.Type != "get" && stanza.Type != "set" {
					continue
				}
				reply := s.processIQ(stanza)
				if reply == nil {
					reply = xmpp.ErrorReply{
						Type:  "cancel",
						Error: xmpp.ErrorBadRequest{},
					}
				}
				if err := s.conn.SendIQReply(stanza.From, "result", stanza.Id, reply); err != nil {
					alert(term, "Failed to send IQ message: "+err.Error())
				}
			default:
				info(term, fmt.Sprintf("%s %s", rawStanza.Name, rawStanza.Value))
			}
		}
	}

	os.Stdout.Write([]byte("\n"))
}
Exemple #11
0
func doRewritePackage(pkg *build.Package, st *rewriteState, opts *rewriteOptions) error {
	libraryMode := opts.LibraryMode(pkg)
	abs, err := filepath.Abs(pkg.Dir)
	if err != nil {
		return err
	}
	fset := token.NewFileSet()
	var names []string
	names = append(names, pkg.GoFiles...)
	names = append(names, pkg.CgoFiles...)
	files, err := parseFiles(fset, abs, names, parser.ParseComments)
	if err != nil {
		return err
	}
	// First check if we should keep any original imports in the package due to
	// the use it makes of the imported pkg (type assertions, etc...).
	disabled := make(map[string]bool)
	for _, v := range files {
		imports := astutil.Imports(fset, v)
		for _, group := range imports {
			for _, imp := range group {
				if unquoted, err := strconv.Unquote(imp.Path.Value); err == nil {
					m := repositoryRe.FindStringSubmatch(unquoted)
					if len(m) > 0 && shouldKeepOriginalImport(fset, unquoted, imp, v, opts) {
						disabled[unquoted] = true
					}
				}
			}
		}
	}
	using := make(map[string]bool)
	for _, v := range files {
		imports := astutil.Imports(fset, v)
		for _, group := range imports {
			for _, imp := range group {
				if unquoted, err := strconv.Unquote(imp.Path.Value); err == nil {
					m := repositoryRe.FindStringSubmatch(unquoted)
					if len(m) > 0 && !disabled[unquoted] {
						using[m[0]] = true
					}
				}
			}
		}
	}
	// Now check imports we should rewrite
	if len(using) == 0 {
		return nil
	}
	var repoNames []string
	for k := range using {
		repoNames = append(repoNames, k)
	}
	if opts.Verbose {
		fmt.Printf("package %s uses %d 3rd party repositories: %v\n", pkgName(pkg), len(repoNames), repoNames)
	}
	repos, err := st.RequestRepos(repoNames)
	if err != nil {
		return err
	}
	rewrites := make(map[string]string)
addRewrites:
	for _, v := range repos {
		var importPath string
		if libraryMode {
			if v.Version == 0 {
				if v.AllowsUnpinned {
					importPath = v.GoPkgsPath
				} else {
					if opts.Verbose {
						fmt.Printf("ignoring package %s, no versions available\n", v.Path)
					}
					continue
				}
			} else {
				importPath = v.VersionImportPath()
			}
		} else {
			if opts.PreferRevisions {
				importPath = v.RevisionImportPath()
			} else {
				importPath = v.VersionImportPath()
			}
		}
		if opts.Interactive {
		prompt:
			for {
				fmt.Printf("rewrite import %s to %s in package %s? (y/N)", v.Path, importPath, pkgName(pkg))
				oldState, err := terminal.MakeRaw(0)
				if err != nil {
					panic(err)
				}
				var buf [1]byte
				os.Stdin.Read(buf[:])
				terminal.Restore(0, oldState)
				fmt.Print("\n")
				switch buf[0] {
				case 'y', 'Y':
					break prompt
				case 'n', 'N', '\r': // /r is enter
					continue addRewrites
				case '\x03', '\x01':
					// ctrl+c, ctrl+z
					os.Exit(0)
				}
			}

		}
		rewrites[v.Path] = importPath
	}
	if len(rewrites) == 0 {
		return nil
	}
	// TODO go get new imports
	return rewriteImports(fset, pkg, files, rewrites, st, opts)
}
Exemple #12
0
func (sshToContainerCmd) Run(context *cmd.Context, _ *cmd.Client) error {
	serverURL, err := cmd.GetURL("/docker/ssh/" + context.Args[0])
	if err != nil {
		return err
	}
	request, err := http.NewRequest("GET", serverURL, nil)
	if err != nil {
		return err
	}
	request.Close = true
	token, err := cmd.ReadToken()
	if err == nil {
		request.Header.Set("Authorization", "bearer "+token)
	}
	parsedURL, _ := url.Parse(serverURL)
	conn, err := net.Dial("tcp", parsedURL.Host)
	if err != nil {
		return err
	}
	defer conn.Close()
	request.Write(conn)
	if stdin, ok := context.Stdin.(*os.File); ok {
		fd := int(stdin.Fd())
		if terminal.IsTerminal(fd) {
			oldState, err := terminal.MakeRaw(fd)
			if err != nil {
				return err
			}
			defer terminal.Restore(fd, oldState)
			sigChan := make(chan os.Signal, 2)
			go func(c <-chan os.Signal) {
				if _, ok := <-c; ok {
					terminal.Restore(fd, oldState)
					os.Exit(1)
				}
			}(sigChan)
			signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM, syscall.SIGKILL, syscall.SIGQUIT)
		}
	}
	bytesLimit := 50
	var readStr string
	byteBuffer := make([]byte, 1)
	for i := 0; i < bytesLimit && byteBuffer[0] != '\n'; i++ {
		_, err := conn.Read(byteBuffer)
		if err != nil {
			break
		}
		readStr += string(byteBuffer)
	}
	matches := httpHeaderRegexp.FindAllStringSubmatch(readStr, -1)
	if len(matches) > 0 && len(matches[0]) > 1 {
		code, _ := strconv.Atoi(matches[0][1])
		return &errors.HTTP{
			Code:    code,
			Message: strings.TrimSpace(readStr),
		}
	} else {
		context.Stdout.Write([]byte(readStr))
	}
	errs := make(chan error, 2)
	quit := make(chan bool)
	go io.Copy(conn, context.Stdin)
	go func() {
		defer close(quit)
		_, err := io.Copy(context.Stdout, conn)
		if err != nil && err != io.EOF {
			errs <- err
		}
	}()
	<-quit
	close(errs)
	return <-errs
}
Exemple #13
0
func run() error {
	fset := twik.NewFileSet()
	scope := twik.NewDefaultScope(fset)
	scope.Create("printf", printfFn)
	scope.Create("list", listFn)

	if len(os.Args) > 1 {
		if strings.HasPrefix(os.Args[1], "-") {
			return fmt.Errorf("usage: twik [<source file>]")
		}
		f, err := os.Open(os.Args[1])
		if err != nil {
			return err
		}
		defer f.Close()
		data, err := ioutil.ReadAll(f)
		if err != nil {
			return err
		}
		node, err := twik.Parse(fset, os.Args[1], data)
		if err != nil {
			return err
		}

		_, err = scope.Eval(node)
		return err
	}

	state, err := terminal.MakeRaw(1)
	if err != nil {
		return err
	}
	defer terminal.Restore(1, state)

	t := terminal.NewTerminal(os.Stdout, "> ")
	unclosed := ""
	for {
		line, err := t.ReadLine()
		if err == io.EOF {
			break
		}
		if err != nil {
			return err
		}
		if unclosed != "" {
			line = unclosed + "\n" + line
		}
		unclosed = ""
		t.SetPrompt("> ")
		node, err := twik.ParseString(fset, "", line)
		if err != nil {
			if strings.HasSuffix(err.Error(), "missing )") {
				unclosed = line
				t.SetPrompt(". ")
				continue
			}
			fmt.Println(err)
			continue
		}
		value, err := scope.Eval(node)
		if err != nil {
			fmt.Println(err)
			continue
		}
		if value != nil {
			if reflect.TypeOf(value).Kind() == reflect.Func {
				fmt.Println("#func")
			} else if v, ok := value.([]interface{}); ok {
				if len(v) == 0 {
					fmt.Println("()")
				} else {
					fmt.Print("(list")
					for _, e := range v {
						fmt.Printf(" %#v", e)
					}
					fmt.Println(")")
				}
			} else {
				fmt.Printf("%#v\n", value)
			}
		}
	}
	fmt.Println()
	return nil
}
Exemple #14
0
// Shell opens a shell connection on the servives ssh address.
func Shell(app *schemas.Application, service *schemas.Service) error {
	// Make sure we're in raw mode.
	termState, err := terminal.MakeRaw(int(os.Stdin.Fd()))
	if err != nil {
		if prompt.IsNotTerminal(err) {
			return errors.ErrIORedirection
		}

		return errors.NewStackError(err)
	}
	defer terminal.Restore(int(os.Stdin.Fd()), termState)

	// Get terminal size.
	cols, rows, err := terminal.GetSize(int(os.Stdout.Fd()))
	if err != nil {
		if prompt.IsNotTerminal(err) {
			return errors.ErrIORedirection
		}

		return errors.NewStackError(err)
	}

	// Open an SSH connection to the address.
	config := &ssh.ClientConfig{User: "******", Auth: []ssh.AuthMethod{
		ssh.Password("password"),
	}}
	client, err := ssh.Dial("tcp", service.SSHAddr, config)
	if err != nil {
		return errors.NewStackError(err)
	}
	defer client.Close()

	// Start a session on the client.
	session, err := client.NewSession()
	if err != nil {
		return errors.NewStackError(err)
	}
	defer session.Close()
	session.Stdout = prompt.NewAnsiWriter(os.Stdout)
	session.Stderr = prompt.NewAnsiWriter(os.Stderr)

	// Create a stdin pipe copying os.Stdin to it.
	stdin, err := session.StdinPipe()
	if err != nil {
		return errors.NewStackError(err)
	}
	defer stdin.Close()

	go func() {
		io.Copy(stdin, prompt.NewAnsiReader(os.Stdin))
	}()

	log.Println("magenta", "Welcome to Bowery Services.")
	log.Println("magenta", "---------------------------------------------")
	log.Println("magenta", "Name:", service.Name)
	log.Println("magenta", "Application:", app.ID)
	log.Println("magenta", "Time:", time.Now())
	log.Println("magenta", "---------------------------------------------")

	// Start a shell session.
	termModes := ssh.TerminalModes{
		ssh.ECHO:          1,
		ssh.TTY_OP_ISPEED: 14400,
		ssh.TTY_OP_OSPEED: 14400,
	}
	err = session.RequestPty("xterm", rows, cols, termModes)
	if err == nil {
		err = session.Shell()
	}
	if err != nil {
		return errors.NewStackError(err)
	}

	// Wait for the session.
	err = session.Wait()
	if err != nil && err != io.EOF {
		// Ignore the error if it's an ExitError with an empty message,
		// this occurs when you do CTRL+c and then run exit cmd which isn't an
		// actual error.
		waitMsg, ok := err.(*ssh.ExitError)
		if ok && waitMsg.Msg() == "" {
			return nil
		}

		return errors.NewStackError(err)
	}

	return nil
}
Exemple #15
0
func main() {
	flag.Parse()
	w := eval.NewWorld()
	if *filename != "" {
		data, err := ioutil.ReadFile(*filename)
		if err != nil {
			fmt.Println(err.Error())
			os.Exit(1)
		}
		file, err := parser.ParseFile(fset, *filename, data, 0)
		if err != nil {
			fmt.Println(err.Error())
			os.Exit(1)
		}
		files := []*ast.File{file}
		code, err := w.CompilePackage(fset, files, "main")
		if err != nil {
			if list, ok := err.(scanner.ErrorList); ok {
				for _, e := range list {
					fmt.Println(e.Error())
				}
			} else {
				fmt.Println(err.Error())
			}
			os.Exit(1)
		}
		code, err = w.Compile(fset, "main()")
		if err != nil {
			fmt.Println(err.Error())
			os.Exit(1)
		}
		_, err = code.Run()
		if err != nil {
			fmt.Println(err.Error())
			os.Exit(1)
		}
		os.Exit(0)
	}

	fmt.Println(":: welcome to go-eval...\n(hit ^D to exit)")

	fd := int(os.Stdin.Fd())
	oldState, err := terminal.MakeRaw(fd)
	if err != nil {
		panic(err)
	}
	defer terminal.Restore(fd, oldState)
	term := terminal.NewTerminal(&shell{r: os.Stdin, w: os.Stdout}, "> ")
	if term == nil {
		panic(errors.New("could not create terminal"))
	}

	for {
		line, err := term.ReadLine()
		if err != nil {
			break
		}
		code, err := w.Compile(fset, line)
		if err != nil {
			term.Write([]byte(err.Error() + "\n"))
			continue
		}
		v, err := code.Run()
		if err != nil {
			term.Write([]byte(err.Error() + "\n"))
			continue
		}
		if v != nil {
			term.Write([]byte(v.String() + "\n"))
		}
	}
}