http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/8fbdb372/br/Godeps/_workspace/src/golang.org/x/crypto/ssh/terminal/terminal.go
----------------------------------------------------------------------
diff --git 
a/br/Godeps/_workspace/src/golang.org/x/crypto/ssh/terminal/terminal.go 
b/br/Godeps/_workspace/src/golang.org/x/crypto/ssh/terminal/terminal.go
new file mode 100644
index 0000000..741eeb1
--- /dev/null
+++ b/br/Godeps/_workspace/src/golang.org/x/crypto/ssh/terminal/terminal.go
@@ -0,0 +1,892 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package terminal
+
+import (
+       "bytes"
+       "io"
+       "sync"
+       "unicode/utf8"
+)
+
+// EscapeCodes contains escape sequences that can be written to the terminal in
+// order to achieve different styles of text.
+type EscapeCodes struct {
+       // Foreground colors
+       Black, Red, Green, Yellow, Blue, Magenta, Cyan, White []byte
+
+       // Reset all attributes
+       Reset []byte
+}
+
+var vt100EscapeCodes = EscapeCodes{
+       Black:   []byte{keyEscape, '[', '3', '0', 'm'},
+       Red:     []byte{keyEscape, '[', '3', '1', 'm'},
+       Green:   []byte{keyEscape, '[', '3', '2', 'm'},
+       Yellow:  []byte{keyEscape, '[', '3', '3', 'm'},
+       Blue:    []byte{keyEscape, '[', '3', '4', 'm'},
+       Magenta: []byte{keyEscape, '[', '3', '5', 'm'},
+       Cyan:    []byte{keyEscape, '[', '3', '6', 'm'},
+       White:   []byte{keyEscape, '[', '3', '7', 'm'},
+
+       Reset: []byte{keyEscape, '[', '0', 'm'},
+}
+
+// Terminal contains the state for running a VT100 terminal that is capable of
+// reading lines of input.
+type Terminal struct {
+       // AutoCompleteCallback, if non-null, is called for each keypress with
+       // the full input line and the current position of the cursor (in
+       // bytes, as an index into |line|). If it returns ok=false, the key
+       // press is processed normally. Otherwise it returns a replacement line
+       // and the new cursor position.
+       AutoCompleteCallback func(line string, pos int, key rune) (newLine 
string, newPos int, ok bool)
+
+       // Escape contains a pointer to the escape codes for this terminal.
+       // It's always a valid pointer, although the escape codes themselves
+       // may be empty if the terminal doesn't support them.
+       Escape *EscapeCodes
+
+       // lock protects the terminal and the state in this object from
+       // concurrent processing of a key press and a Write() call.
+       lock sync.Mutex
+
+       c      io.ReadWriter
+       prompt []rune
+
+       // line is the current line being entered.
+       line []rune
+       // pos is the logical position of the cursor in line
+       pos int
+       // echo is true if local echo is enabled
+       echo bool
+       // pasteActive is true iff there is a bracketed paste operation in
+       // progress.
+       pasteActive bool
+
+       // cursorX contains the current X value of the cursor where the left
+       // edge is 0. cursorY contains the row number where the first row of
+       // the current line is 0.
+       cursorX, cursorY int
+       // maxLine is the greatest value of cursorY so far.
+       maxLine int
+
+       termWidth, termHeight int
+
+       // outBuf contains the terminal data to be sent.
+       outBuf []byte
+       // remainder contains the remainder of any partial key sequences after
+       // a read. It aliases into inBuf.
+       remainder []byte
+       inBuf     [256]byte
+
+       // history contains previously entered commands so that they can be
+       // accessed with the up and down keys.
+       history stRingBuffer
+       // historyIndex stores the currently accessed history entry, where zero
+       // means the immediately previous entry.
+       historyIndex int
+       // When navigating up and down the history it's possible to return to
+       // the incomplete, initial line. That value is stored in
+       // historyPending.
+       historyPending string
+}
+
+// NewTerminal runs a VT100 terminal on the given ReadWriter. If the 
ReadWriter is
+// a local terminal, that terminal must first have been put into raw mode.
+// prompt is a string that is written at the start of each input line (i.e.
+// "> ").
+func NewTerminal(c io.ReadWriter, prompt string) *Terminal {
+       return &Terminal{
+               Escape:       &vt100EscapeCodes,
+               c:            c,
+               prompt:       []rune(prompt),
+               termWidth:    80,
+               termHeight:   24,
+               echo:         true,
+               historyIndex: -1,
+       }
+}
+
+const (
+       keyCtrlD     = 4
+       keyCtrlU     = 21
+       keyEnter     = '\r'
+       keyEscape    = 27
+       keyBackspace = 127
+       keyUnknown   = 0xd800 /* UTF-16 surrogate area */ + iota
+       keyUp
+       keyDown
+       keyLeft
+       keyRight
+       keyAltLeft
+       keyAltRight
+       keyHome
+       keyEnd
+       keyDeleteWord
+       keyDeleteLine
+       keyClearScreen
+       keyPasteStart
+       keyPasteEnd
+)
+
+var pasteStart = []byte{keyEscape, '[', '2', '0', '0', '~'}
+var pasteEnd = []byte{keyEscape, '[', '2', '0', '1', '~'}
+
+// bytesToKey tries to parse a key sequence from b. If successful, it returns
+// the key and the remainder of the input. Otherwise it returns utf8.RuneError.
+func bytesToKey(b []byte, pasteActive bool) (rune, []byte) {
+       if len(b) == 0 {
+               return utf8.RuneError, nil
+       }
+
+       if !pasteActive {
+               switch b[0] {
+               case 1: // ^A
+                       return keyHome, b[1:]
+               case 5: // ^E
+                       return keyEnd, b[1:]
+               case 8: // ^H
+                       return keyBackspace, b[1:]
+               case 11: // ^K
+                       return keyDeleteLine, b[1:]
+               case 12: // ^L
+                       return keyClearScreen, b[1:]
+               case 23: // ^W
+                       return keyDeleteWord, b[1:]
+               }
+       }
+
+       if b[0] != keyEscape {
+               if !utf8.FullRune(b) {
+                       return utf8.RuneError, b
+               }
+               r, l := utf8.DecodeRune(b)
+               return r, b[l:]
+       }
+
+       if !pasteActive && len(b) >= 3 && b[0] == keyEscape && b[1] == '[' {
+               switch b[2] {
+               case 'A':
+                       return keyUp, b[3:]
+               case 'B':
+                       return keyDown, b[3:]
+               case 'C':
+                       return keyRight, b[3:]
+               case 'D':
+                       return keyLeft, b[3:]
+               case 'H':
+                       return keyHome, b[3:]
+               case 'F':
+                       return keyEnd, b[3:]
+               }
+       }
+
+       if !pasteActive && len(b) >= 6 && b[0] == keyEscape && b[1] == '[' && 
b[2] == '1' && b[3] == ';' && b[4] == '3' {
+               switch b[5] {
+               case 'C':
+                       return keyAltRight, b[6:]
+               case 'D':
+                       return keyAltLeft, b[6:]
+               }
+       }
+
+       if !pasteActive && len(b) >= 6 && bytes.Equal(b[:6], pasteStart) {
+               return keyPasteStart, b[6:]
+       }
+
+       if pasteActive && len(b) >= 6 && bytes.Equal(b[:6], pasteEnd) {
+               return keyPasteEnd, b[6:]
+       }
+
+       // If we get here then we have a key that we don't recognise, or a
+       // partial sequence. It's not clear how one should find the end of a
+       // sequence without knowing them all, but it seems that [a-zA-Z~] only
+       // appears at the end of a sequence.
+       for i, c := range b[0:] {
+               if c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '~' {
+                       return keyUnknown, b[i+1:]
+               }
+       }
+
+       return utf8.RuneError, b
+}
+
+// queue appends data to the end of t.outBuf
+func (t *Terminal) queue(data []rune) {
+       t.outBuf = append(t.outBuf, []byte(string(data))...)
+}
+
+var eraseUnderCursor = []rune{' ', keyEscape, '[', 'D'}
+var space = []rune{' '}
+
+func isPrintable(key rune) bool {
+       isInSurrogateArea := key >= 0xd800 && key <= 0xdbff
+       return key >= 32 && !isInSurrogateArea
+}
+
+// moveCursorToPos appends data to t.outBuf which will move the cursor to the
+// given, logical position in the text.
+func (t *Terminal) moveCursorToPos(pos int) {
+       if !t.echo {
+               return
+       }
+
+       x := visualLength(t.prompt) + pos
+       y := x / t.termWidth
+       x = x % t.termWidth
+
+       up := 0
+       if y < t.cursorY {
+               up = t.cursorY - y
+       }
+
+       down := 0
+       if y > t.cursorY {
+               down = y - t.cursorY
+       }
+
+       left := 0
+       if x < t.cursorX {
+               left = t.cursorX - x
+       }
+
+       right := 0
+       if x > t.cursorX {
+               right = x - t.cursorX
+       }
+
+       t.cursorX = x
+       t.cursorY = y
+       t.move(up, down, left, right)
+}
+
+func (t *Terminal) move(up, down, left, right int) {
+       movement := make([]rune, 3*(up+down+left+right))
+       m := movement
+       for i := 0; i < up; i++ {
+               m[0] = keyEscape
+               m[1] = '['
+               m[2] = 'A'
+               m = m[3:]
+       }
+       for i := 0; i < down; i++ {
+               m[0] = keyEscape
+               m[1] = '['
+               m[2] = 'B'
+               m = m[3:]
+       }
+       for i := 0; i < left; i++ {
+               m[0] = keyEscape
+               m[1] = '['
+               m[2] = 'D'
+               m = m[3:]
+       }
+       for i := 0; i < right; i++ {
+               m[0] = keyEscape
+               m[1] = '['
+               m[2] = 'C'
+               m = m[3:]
+       }
+
+       t.queue(movement)
+}
+
+func (t *Terminal) clearLineToRight() {
+       op := []rune{keyEscape, '[', 'K'}
+       t.queue(op)
+}
+
+const maxLineLength = 4096
+
+func (t *Terminal) setLine(newLine []rune, newPos int) {
+       if t.echo {
+               t.moveCursorToPos(0)
+               t.writeLine(newLine)
+               for i := len(newLine); i < len(t.line); i++ {
+                       t.writeLine(space)
+               }
+               t.moveCursorToPos(newPos)
+       }
+       t.line = newLine
+       t.pos = newPos
+}
+
+func (t *Terminal) advanceCursor(places int) {
+       t.cursorX += places
+       t.cursorY += t.cursorX / t.termWidth
+       if t.cursorY > t.maxLine {
+               t.maxLine = t.cursorY
+       }
+       t.cursorX = t.cursorX % t.termWidth
+
+       if places > 0 && t.cursorX == 0 {
+               // Normally terminals will advance the current position
+               // when writing a character. But that doesn't happen
+               // for the last character in a line. However, when
+               // writing a character (except a new line) that causes
+               // a line wrap, the position will be advanced two
+               // places.
+               //
+               // So, if we are stopping at the end of a line, we
+               // need to write a newline so that our cursor can be
+               // advanced to the next line.
+               t.outBuf = append(t.outBuf, '\n')
+       }
+}
+
+func (t *Terminal) eraseNPreviousChars(n int) {
+       if n == 0 {
+               return
+       }
+
+       if t.pos < n {
+               n = t.pos
+       }
+       t.pos -= n
+       t.moveCursorToPos(t.pos)
+
+       copy(t.line[t.pos:], t.line[n+t.pos:])
+       t.line = t.line[:len(t.line)-n]
+       if t.echo {
+               t.writeLine(t.line[t.pos:])
+               for i := 0; i < n; i++ {
+                       t.queue(space)
+               }
+               t.advanceCursor(n)
+               t.moveCursorToPos(t.pos)
+       }
+}
+
+// countToLeftWord returns then number of characters from the cursor to the
+// start of the previous word.
+func (t *Terminal) countToLeftWord() int {
+       if t.pos == 0 {
+               return 0
+       }
+
+       pos := t.pos - 1
+       for pos > 0 {
+               if t.line[pos] != ' ' {
+                       break
+               }
+               pos--
+       }
+       for pos > 0 {
+               if t.line[pos] == ' ' {
+                       pos++
+                       break
+               }
+               pos--
+       }
+
+       return t.pos - pos
+}
+
+// countToRightWord returns then number of characters from the cursor to the
+// start of the next word.
+func (t *Terminal) countToRightWord() int {
+       pos := t.pos
+       for pos < len(t.line) {
+               if t.line[pos] == ' ' {
+                       break
+               }
+               pos++
+       }
+       for pos < len(t.line) {
+               if t.line[pos] != ' ' {
+                       break
+               }
+               pos++
+       }
+       return pos - t.pos
+}
+
+// visualLength returns the number of visible glyphs in s.
+func visualLength(runes []rune) int {
+       inEscapeSeq := false
+       length := 0
+
+       for _, r := range runes {
+               switch {
+               case inEscapeSeq:
+                       if (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') {
+                               inEscapeSeq = false
+                       }
+               case r == '\x1b':
+                       inEscapeSeq = true
+               default:
+                       length++
+               }
+       }
+
+       return length
+}
+
+// handleKey processes the given key and, optionally, returns a line of text
+// that the user has entered.
+func (t *Terminal) handleKey(key rune) (line string, ok bool) {
+       if t.pasteActive && key != keyEnter {
+               t.addKeyToLine(key)
+               return
+       }
+
+       switch key {
+       case keyBackspace:
+               if t.pos == 0 {
+                       return
+               }
+               t.eraseNPreviousChars(1)
+       case keyAltLeft:
+               // move left by a word.
+               t.pos -= t.countToLeftWord()
+               t.moveCursorToPos(t.pos)
+       case keyAltRight:
+               // move right by a word.
+               t.pos += t.countToRightWord()
+               t.moveCursorToPos(t.pos)
+       case keyLeft:
+               if t.pos == 0 {
+                       return
+               }
+               t.pos--
+               t.moveCursorToPos(t.pos)
+       case keyRight:
+               if t.pos == len(t.line) {
+                       return
+               }
+               t.pos++
+               t.moveCursorToPos(t.pos)
+       case keyHome:
+               if t.pos == 0 {
+                       return
+               }
+               t.pos = 0
+               t.moveCursorToPos(t.pos)
+       case keyEnd:
+               if t.pos == len(t.line) {
+                       return
+               }
+               t.pos = len(t.line)
+               t.moveCursorToPos(t.pos)
+       case keyUp:
+               entry, ok := t.history.NthPreviousEntry(t.historyIndex + 1)
+               if !ok {
+                       return "", false
+               }
+               if t.historyIndex == -1 {
+                       t.historyPending = string(t.line)
+               }
+               t.historyIndex++
+               runes := []rune(entry)
+               t.setLine(runes, len(runes))
+       case keyDown:
+               switch t.historyIndex {
+               case -1:
+                       return
+               case 0:
+                       runes := []rune(t.historyPending)
+                       t.setLine(runes, len(runes))
+                       t.historyIndex--
+               default:
+                       entry, ok := t.history.NthPreviousEntry(t.historyIndex 
- 1)
+                       if ok {
+                               t.historyIndex--
+                               runes := []rune(entry)
+                               t.setLine(runes, len(runes))
+                       }
+               }
+       case keyEnter:
+               t.moveCursorToPos(len(t.line))
+               t.queue([]rune("\r\n"))
+               line = string(t.line)
+               ok = true
+               t.line = t.line[:0]
+               t.pos = 0
+               t.cursorX = 0
+               t.cursorY = 0
+               t.maxLine = 0
+       case keyDeleteWord:
+               // Delete zero or more spaces and then one or more characters.
+               t.eraseNPreviousChars(t.countToLeftWord())
+       case keyDeleteLine:
+               // Delete everything from the current cursor position to the
+               // end of line.
+               for i := t.pos; i < len(t.line); i++ {
+                       t.queue(space)
+                       t.advanceCursor(1)
+               }
+               t.line = t.line[:t.pos]
+               t.moveCursorToPos(t.pos)
+       case keyCtrlD:
+               // Erase the character under the current position.
+               // The EOF case when the line is empty is handled in
+               // readLine().
+               if t.pos < len(t.line) {
+                       t.pos++
+                       t.eraseNPreviousChars(1)
+               }
+       case keyCtrlU:
+               t.eraseNPreviousChars(t.pos)
+       case keyClearScreen:
+               // Erases the screen and moves the cursor to the home position.
+               t.queue([]rune("\x1b[2J\x1b[H"))
+               t.queue(t.prompt)
+               t.cursorX, t.cursorY = 0, 0
+               t.advanceCursor(visualLength(t.prompt))
+               t.setLine(t.line, t.pos)
+       default:
+               if t.AutoCompleteCallback != nil {
+                       prefix := string(t.line[:t.pos])
+                       suffix := string(t.line[t.pos:])
+
+                       t.lock.Unlock()
+                       newLine, newPos, completeOk := 
t.AutoCompleteCallback(prefix+suffix, len(prefix), key)
+                       t.lock.Lock()
+
+                       if completeOk {
+                               t.setLine([]rune(newLine), 
utf8.RuneCount([]byte(newLine)[:newPos]))
+                               return
+                       }
+               }
+               if !isPrintable(key) {
+                       return
+               }
+               if len(t.line) == maxLineLength {
+                       return
+               }
+               t.addKeyToLine(key)
+       }
+       return
+}
+
+// addKeyToLine inserts the given key at the current position in the current
+// line.
+func (t *Terminal) addKeyToLine(key rune) {
+       if len(t.line) == cap(t.line) {
+               newLine := make([]rune, len(t.line), 2*(1+len(t.line)))
+               copy(newLine, t.line)
+               t.line = newLine
+       }
+       t.line = t.line[:len(t.line)+1]
+       copy(t.line[t.pos+1:], t.line[t.pos:])
+       t.line[t.pos] = key
+       if t.echo {
+               t.writeLine(t.line[t.pos:])
+       }
+       t.pos++
+       t.moveCursorToPos(t.pos)
+}
+
+func (t *Terminal) writeLine(line []rune) {
+       for len(line) != 0 {
+               remainingOnLine := t.termWidth - t.cursorX
+               todo := len(line)
+               if todo > remainingOnLine {
+                       todo = remainingOnLine
+               }
+               t.queue(line[:todo])
+               t.advanceCursor(visualLength(line[:todo]))
+               line = line[todo:]
+       }
+}
+
+func (t *Terminal) Write(buf []byte) (n int, err error) {
+       t.lock.Lock()
+       defer t.lock.Unlock()
+
+       if t.cursorX == 0 && t.cursorY == 0 {
+               // This is the easy case: there's nothing on the screen that we
+               // have to move out of the way.
+               return t.c.Write(buf)
+       }
+
+       // We have a prompt and possibly user input on the screen. We
+       // have to clear it first.
+       t.move(0 /* up */, 0 /* down */, t.cursorX /* left */, 0 /* right */)
+       t.cursorX = 0
+       t.clearLineToRight()
+
+       for t.cursorY > 0 {
+               t.move(1 /* up */, 0, 0, 0)
+               t.cursorY--
+               t.clearLineToRight()
+       }
+
+       if _, err = t.c.Write(t.outBuf); err != nil {
+               return
+       }
+       t.outBuf = t.outBuf[:0]
+
+       if n, err = t.c.Write(buf); err != nil {
+               return
+       }
+
+       t.writeLine(t.prompt)
+       if t.echo {
+               t.writeLine(t.line)
+       }
+
+       t.moveCursorToPos(t.pos)
+
+       if _, err = t.c.Write(t.outBuf); err != nil {
+               return
+       }
+       t.outBuf = t.outBuf[:0]
+       return
+}
+
+// ReadPassword temporarily changes the prompt and reads a password, without
+// echo, from the terminal.
+func (t *Terminal) ReadPassword(prompt string) (line string, err error) {
+       t.lock.Lock()
+       defer t.lock.Unlock()
+
+       oldPrompt := t.prompt
+       t.prompt = []rune(prompt)
+       t.echo = false
+
+       line, err = t.readLine()
+
+       t.prompt = oldPrompt
+       t.echo = true
+
+       return
+}
+
+// ReadLine returns a line of input from the terminal.
+func (t *Terminal) ReadLine() (line string, err error) {
+       t.lock.Lock()
+       defer t.lock.Unlock()
+
+       return t.readLine()
+}
+
+func (t *Terminal) readLine() (line string, err error) {
+       // t.lock must be held at this point
+
+       if t.cursorX == 0 && t.cursorY == 0 {
+               t.writeLine(t.prompt)
+               t.c.Write(t.outBuf)
+               t.outBuf = t.outBuf[:0]
+       }
+
+       lineIsPasted := t.pasteActive
+
+       for {
+               rest := t.remainder
+               lineOk := false
+               for !lineOk {
+                       var key rune
+                       key, rest = bytesToKey(rest, t.pasteActive)
+                       if key == utf8.RuneError {
+                               break
+                       }
+                       if !t.pasteActive {
+                               if key == keyCtrlD {
+                                       if len(t.line) == 0 {
+                                               return "", io.EOF
+                                       }
+                               }
+                               if key == keyPasteStart {
+                                       t.pasteActive = true
+                                       if len(t.line) == 0 {
+                                               lineIsPasted = true
+                                       }
+                                       continue
+                               }
+                       } else if key == keyPasteEnd {
+                               t.pasteActive = false
+                               continue
+                       }
+                       if !t.pasteActive {
+                               lineIsPasted = false
+                       }
+                       line, lineOk = t.handleKey(key)
+               }
+               if len(rest) > 0 {
+                       n := copy(t.inBuf[:], rest)
+                       t.remainder = t.inBuf[:n]
+               } else {
+                       t.remainder = nil
+               }
+               t.c.Write(t.outBuf)
+               t.outBuf = t.outBuf[:0]
+               if lineOk {
+                       if t.echo {
+                               t.historyIndex = -1
+                               t.history.Add(line)
+                       }
+                       if lineIsPasted {
+                               err = ErrPasteIndicator
+                       }
+                       return
+               }
+
+               // t.remainder is a slice at the beginning of t.inBuf
+               // containing a partial key sequence
+               readBuf := t.inBuf[len(t.remainder):]
+               var n int
+
+               t.lock.Unlock()
+               n, err = t.c.Read(readBuf)
+               t.lock.Lock()
+
+               if err != nil {
+                       return
+               }
+
+               t.remainder = t.inBuf[:n+len(t.remainder)]
+       }
+
+       panic("unreachable") // for Go 1.0.
+}
+
+// SetPrompt sets the prompt to be used when reading subsequent lines.
+func (t *Terminal) SetPrompt(prompt string) {
+       t.lock.Lock()
+       defer t.lock.Unlock()
+
+       t.prompt = []rune(prompt)
+}
+
+func (t *Terminal) clearAndRepaintLinePlusNPrevious(numPrevLines int) {
+       // Move cursor to column zero at the start of the line.
+       t.move(t.cursorY, 0, t.cursorX, 0)
+       t.cursorX, t.cursorY = 0, 0
+       t.clearLineToRight()
+       for t.cursorY < numPrevLines {
+               // Move down a line
+               t.move(0, 1, 0, 0)
+               t.cursorY++
+               t.clearLineToRight()
+       }
+       // Move back to beginning.
+       t.move(t.cursorY, 0, 0, 0)
+       t.cursorX, t.cursorY = 0, 0
+
+       t.queue(t.prompt)
+       t.advanceCursor(visualLength(t.prompt))
+       t.writeLine(t.line)
+       t.moveCursorToPos(t.pos)
+}
+
+func (t *Terminal) SetSize(width, height int) error {
+       t.lock.Lock()
+       defer t.lock.Unlock()
+
+       if width == 0 {
+               width = 1
+       }
+
+       oldWidth := t.termWidth
+       t.termWidth, t.termHeight = width, height
+
+       switch {
+       case width == oldWidth:
+               // If the width didn't change then nothing else needs to be
+               // done.
+               return nil
+       case len(t.line) == 0 && t.cursorX == 0 && t.cursorY == 0:
+               // If there is nothing on current line and no prompt printed,
+               // just do nothing
+               return nil
+       case width < oldWidth:
+               // Some terminals (e.g. xterm) will truncate lines that were
+               // too long when shinking. Others, (e.g. gnome-terminal) will
+               // attempt to wrap them. For the former, repainting t.maxLine
+               // works great, but that behaviour goes badly wrong in the case
+               // of the latter because they have doubled every full line.
+
+               // We assume that we are working on a terminal that wraps lines
+               // and adjust the cursor position based on every previous line
+               // wrapping and turning into two. This causes the prompt on
+               // xterms to move upwards, which isn't great, but it avoids a
+               // huge mess with gnome-terminal.
+               if t.cursorX >= t.termWidth {
+                       t.cursorX = t.termWidth - 1
+               }
+               t.cursorY *= 2
+               t.clearAndRepaintLinePlusNPrevious(t.maxLine * 2)
+       case width > oldWidth:
+               // If the terminal expands then our position calculations will
+               // be wrong in the future because we think the cursor is
+               // |t.pos| chars into the string, but there will be a gap at
+               // the end of any wrapped line.
+               //
+               // But the position will actually be correct until we move, so
+               // we can move back to the beginning and repaint everything.
+               t.clearAndRepaintLinePlusNPrevious(t.maxLine)
+       }
+
+       _, err := t.c.Write(t.outBuf)
+       t.outBuf = t.outBuf[:0]
+       return err
+}
+
+type pasteIndicatorError struct{}
+
+func (pasteIndicatorError) Error() string {
+       return "terminal: ErrPasteIndicator not correctly handled"
+}
+
+// ErrPasteIndicator may be returned from ReadLine as the error, in addition
+// to valid line data. It indicates that bracketed paste mode is enabled and
+// that the returned line consists only of pasted data. Programs may wish to
+// interpret pasted data more literally than typed data.
+var ErrPasteIndicator = pasteIndicatorError{}
+
+// SetBracketedPasteMode requests that the terminal bracket paste operations
+// with markers. Not all terminals support this but, if it is supported, then
+// enabling this mode will stop any autocomplete callback from running due to
+// pastes. Additionally, any lines that are completely pasted will be returned
+// from ReadLine with the error set to ErrPasteIndicator.
+func (t *Terminal) SetBracketedPasteMode(on bool) {
+       if on {
+               io.WriteString(t.c, "\x1b[?2004h")
+       } else {
+               io.WriteString(t.c, "\x1b[?2004l")
+       }
+}
+
+// stRingBuffer is a ring buffer of strings.
+type stRingBuffer struct {
+       // entries contains max elements.
+       entries []string
+       max     int
+       // head contains the index of the element most recently added to the 
ring.
+       head int
+       // size contains the number of elements in the ring.
+       size int
+}
+
+func (s *stRingBuffer) Add(a string) {
+       if s.entries == nil {
+               const defaultNumEntries = 100
+               s.entries = make([]string, defaultNumEntries)
+               s.max = defaultNumEntries
+       }
+
+       s.head = (s.head + 1) % s.max
+       s.entries[s.head] = a
+       if s.size < s.max {
+               s.size++
+       }
+}
+
+// NthPreviousEntry returns the value passed to the nth previous call to Add.
+// If n is zero then the immediately prior value is returned, if one, then the
+// next most recent, and so on. If such an element doesn't exist then ok is
+// false.
+func (s *stRingBuffer) NthPreviousEntry(n int) (value string, ok bool) {
+       if n >= s.size {
+               return "", false
+       }
+       index := s.head - n
+       if index < 0 {
+               index += s.max
+       }
+       return s.entries[index], true
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/8fbdb372/br/Godeps/_workspace/src/golang.org/x/crypto/ssh/terminal/util.go
----------------------------------------------------------------------
diff --git a/br/Godeps/_workspace/src/golang.org/x/crypto/ssh/terminal/util.go 
b/br/Godeps/_workspace/src/golang.org/x/crypto/ssh/terminal/util.go
new file mode 100644
index 0000000..0763c9a
--- /dev/null
+++ b/br/Godeps/_workspace/src/golang.org/x/crypto/ssh/terminal/util.go
@@ -0,0 +1,128 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux,!appengine netbsd openbsd
+
+// Package terminal provides support functions for dealing with terminals, as
+// commonly found on UNIX systems.
+//
+// Putting a terminal into raw mode is the most common requirement:
+//
+//     oldState, err := terminal.MakeRaw(0)
+//     if err != nil {
+//             panic(err)
+//     }
+//     defer terminal.Restore(0, oldState)
+package terminal
+
+import (
+       "io"
+       "syscall"
+       "unsafe"
+)
+
+// State contains the state of a terminal.
+type State struct {
+       termios syscall.Termios
+}
+
+// IsTerminal returns true if the given file descriptor is a terminal.
+func IsTerminal(fd int) bool {
+       var termios syscall.Termios
+       _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), 
ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
+       return err == 0
+}
+
+// MakeRaw put the terminal connected to the given file descriptor into raw
+// mode and returns the previous state of the terminal so that it can be
+// restored.
+func MakeRaw(fd int) (*State, error) {
+       var oldState State
+       if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), 
ioctlReadTermios, uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 
0 {
+               return nil, err
+       }
+
+       newState := oldState.termios
+       newState.Iflag &^= syscall.ISTRIP | syscall.INLCR | syscall.ICRNL | 
syscall.IGNCR | syscall.IXON | syscall.IXOFF
+       newState.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.ISIG
+       if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), 
ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 {
+               return nil, err
+       }
+
+       return &oldState, nil
+}
+
+// GetState returns the current state of a terminal which may be useful to
+// restore the terminal after a signal.
+func GetState(fd int) (*State, error) {
+       var oldState State
+       if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), 
ioctlReadTermios, uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 
0 {
+               return nil, err
+       }
+
+       return &oldState, nil
+}
+
+// Restore restores the terminal connected to the given file descriptor to a
+// previous state.
+func Restore(fd int, state *State) error {
+       _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), 
ioctlWriteTermios, uintptr(unsafe.Pointer(&state.termios)), 0, 0, 0)
+       return err
+}
+
+// GetSize returns the dimensions of the given terminal.
+func GetSize(fd int) (width, height int, err error) {
+       var dimensions [4]uint16
+
+       if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), 
uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&dimensions)), 0, 0, 0); 
err != 0 {
+               return -1, -1, err
+       }
+       return int(dimensions[1]), int(dimensions[0]), nil
+}
+
+// ReadPassword reads a line of input from a terminal without local echo.  This
+// is commonly used for inputting passwords and other sensitive data. The slice
+// returned does not include the \n.
+func ReadPassword(fd int) ([]byte, error) {
+       var oldState syscall.Termios
+       if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), 
ioctlReadTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); err != 0 {
+               return nil, err
+       }
+
+       newState := oldState
+       newState.Lflag &^= syscall.ECHO
+       newState.Lflag |= syscall.ICANON | syscall.ISIG
+       newState.Iflag |= syscall.ICRNL
+       if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), 
ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 {
+               return nil, err
+       }
+
+       defer func() {
+               syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), 
ioctlWriteTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0)
+       }()
+
+       var buf [16]byte
+       var ret []byte
+       for {
+               n, err := syscall.Read(fd, buf[:])
+               if err != nil {
+                       return nil, err
+               }
+               if n == 0 {
+                       if len(ret) == 0 {
+                               return nil, io.EOF
+                       }
+                       break
+               }
+               if buf[n-1] == '\n' {
+                       n--
+               }
+               ret = append(ret, buf[:n]...)
+               if n < len(buf) {
+                       break
+               }
+       }
+
+       return ret, nil
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/8fbdb372/br/Godeps/_workspace/src/golang.org/x/crypto/ssh/terminal/util_bsd.go
----------------------------------------------------------------------
diff --git 
a/br/Godeps/_workspace/src/golang.org/x/crypto/ssh/terminal/util_bsd.go 
b/br/Godeps/_workspace/src/golang.org/x/crypto/ssh/terminal/util_bsd.go
new file mode 100644
index 0000000..9c1ffd1
--- /dev/null
+++ b/br/Godeps/_workspace/src/golang.org/x/crypto/ssh/terminal/util_bsd.go
@@ -0,0 +1,12 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd netbsd openbsd
+
+package terminal
+
+import "syscall"
+
+const ioctlReadTermios = syscall.TIOCGETA
+const ioctlWriteTermios = syscall.TIOCSETA

http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/8fbdb372/br/Godeps/_workspace/src/golang.org/x/crypto/ssh/terminal/util_linux.go
----------------------------------------------------------------------
diff --git 
a/br/Godeps/_workspace/src/golang.org/x/crypto/ssh/terminal/util_linux.go 
b/br/Godeps/_workspace/src/golang.org/x/crypto/ssh/terminal/util_linux.go
new file mode 100644
index 0000000..5883b22
--- /dev/null
+++ b/br/Godeps/_workspace/src/golang.org/x/crypto/ssh/terminal/util_linux.go
@@ -0,0 +1,11 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package terminal
+
+// These constants are declared here, rather than importing
+// them from the syscall package as some syscall packages, even
+// on linux, for example gccgo, do not declare them.
+const ioctlReadTermios = 0x5401  // syscall.TCGETS
+const ioctlWriteTermios = 0x5402 // syscall.TCSETS

http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/8fbdb372/br/Godeps/_workspace/src/golang.org/x/crypto/ssh/terminal/util_windows.go
----------------------------------------------------------------------
diff --git 
a/br/Godeps/_workspace/src/golang.org/x/crypto/ssh/terminal/util_windows.go 
b/br/Godeps/_workspace/src/golang.org/x/crypto/ssh/terminal/util_windows.go
new file mode 100644
index 0000000..2dd6c3d
--- /dev/null
+++ b/br/Godeps/_workspace/src/golang.org/x/crypto/ssh/terminal/util_windows.go
@@ -0,0 +1,174 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+// Package terminal provides support functions for dealing with terminals, as
+// commonly found on UNIX systems.
+//
+// Putting a terminal into raw mode is the most common requirement:
+//
+//     oldState, err := terminal.MakeRaw(0)
+//     if err != nil {
+//             panic(err)
+//     }
+//     defer terminal.Restore(0, oldState)
+package terminal
+
+import (
+       "io"
+       "syscall"
+       "unsafe"
+)
+
+const (
+       enableLineInput       = 2
+       enableEchoInput       = 4
+       enableProcessedInput  = 1
+       enableWindowInput     = 8
+       enableMouseInput      = 16
+       enableInsertMode      = 32
+       enableQuickEditMode   = 64
+       enableExtendedFlags   = 128
+       enableAutoPosition    = 256
+       enableProcessedOutput = 1
+       enableWrapAtEolOutput = 2
+)
+
+var kernel32 = syscall.NewLazyDLL("kernel32.dll")
+
+var (
+       procGetConsoleMode             = kernel32.NewProc("GetConsoleMode")
+       procSetConsoleMode             = kernel32.NewProc("SetConsoleMode")
+       procGetConsoleScreenBufferInfo = 
kernel32.NewProc("GetConsoleScreenBufferInfo")
+)
+
+type (
+       short int16
+       word  uint16
+
+       coord struct {
+               x short
+               y short
+       }
+       smallRect struct {
+               left   short
+               top    short
+               right  short
+               bottom short
+       }
+       consoleScreenBufferInfo struct {
+               size              coord
+               cursorPosition    coord
+               attributes        word
+               window            smallRect
+               maximumWindowSize coord
+       }
+)
+
+type State struct {
+       mode uint32
+}
+
+// IsTerminal returns true if the given file descriptor is a terminal.
+func IsTerminal(fd int) bool {
+       var st uint32
+       r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), 
uintptr(unsafe.Pointer(&st)), 0)
+       return r != 0 && e == 0
+}
+
+// MakeRaw put the terminal connected to the given file descriptor into raw
+// mode and returns the previous state of the terminal so that it can be
+// restored.
+func MakeRaw(fd int) (*State, error) {
+       var st uint32
+       _, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), 
uintptr(unsafe.Pointer(&st)), 0)
+       if e != 0 {
+               return nil, error(e)
+       }
+       st &^= (enableEchoInput | enableProcessedInput | enableLineInput | 
enableProcessedOutput)
+       _, _, e = syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), 
uintptr(st), 0)
+       if e != 0 {
+               return nil, error(e)
+       }
+       return &State{st}, nil
+}
+
+// GetState returns the current state of a terminal which may be useful to
+// restore the terminal after a signal.
+func GetState(fd int) (*State, error) {
+       var st uint32
+       _, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), 
uintptr(unsafe.Pointer(&st)), 0)
+       if e != 0 {
+               return nil, error(e)
+       }
+       return &State{st}, nil
+}
+
+// Restore restores the terminal connected to the given file descriptor to a
+// previous state.
+func Restore(fd int, state *State) error {
+       _, _, err := syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), 
uintptr(state.mode), 0)
+       return err
+}
+
+// GetSize returns the dimensions of the given terminal.
+func GetSize(fd int) (width, height int, err error) {
+       var info consoleScreenBufferInfo
+       _, _, e := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, 
uintptr(fd), uintptr(unsafe.Pointer(&info)), 0)
+       if e != 0 {
+               return 0, 0, error(e)
+       }
+       return int(info.size.x), int(info.size.y), nil
+}
+
+// ReadPassword reads a line of input from a terminal without local echo.  This
+// is commonly used for inputting passwords and other sensitive data. The slice
+// returned does not include the \n.
+func ReadPassword(fd int) ([]byte, error) {
+       var st uint32
+       _, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), 
uintptr(unsafe.Pointer(&st)), 0)
+       if e != 0 {
+               return nil, error(e)
+       }
+       old := st
+
+       st &^= (enableEchoInput)
+       st |= (enableProcessedInput | enableLineInput | enableProcessedOutput)
+       _, _, e = syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), 
uintptr(st), 0)
+       if e != 0 {
+               return nil, error(e)
+       }
+
+       defer func() {
+               syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), 
uintptr(old), 0)
+       }()
+
+       var buf [16]byte
+       var ret []byte
+       for {
+               n, err := syscall.Read(syscall.Handle(fd), buf[:])
+               if err != nil {
+                       return nil, err
+               }
+               if n == 0 {
+                       if len(ret) == 0 {
+                               return nil, io.EOF
+                       }
+                       break
+               }
+               if buf[n-1] == '\n' {
+                       n--
+               }
+               if n > 0 && buf[n-1] == '\r' {
+                       n--
+               }
+               ret = append(ret, buf[:n]...)
+               if n < len(buf) {
+                       break
+               }
+       }
+
+       return ret, nil
+}

Reply via email to