github.com/olivere/camlistore@v0.0.0-20140121221811-1b7ac2da0199/third_party/code.google.com/p/go.crypto/ssh/server_terminal.go (about)

     1  // Copyright 2011 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package ssh
     6  
     7  // A Terminal is capable of parsing and generating virtual terminal
     8  // data from an SSH client.
     9  type Terminal interface {
    10  	ReadLine() (line string, err error)
    11  	SetSize(x, y int)
    12  	Write([]byte) (int, error)
    13  }
    14  
    15  // ServerTerminal contains the state for running a terminal that is capable of
    16  // reading lines of input.
    17  type ServerTerminal struct {
    18  	Term    Terminal
    19  	Channel Channel
    20  }
    21  
    22  // parsePtyRequest parses the payload of the pty-req message and extracts the
    23  // dimensions of the terminal. See RFC 4254, section 6.2.
    24  func parsePtyRequest(s []byte) (width, height int, ok bool) {
    25  	_, s, ok = parseString(s)
    26  	if !ok {
    27  		return
    28  	}
    29  	width32, s, ok := parseUint32(s)
    30  	if !ok {
    31  		return
    32  	}
    33  	height32, _, ok := parseUint32(s)
    34  	width = int(width32)
    35  	height = int(height32)
    36  	if width < 1 {
    37  		ok = false
    38  	}
    39  	if height < 1 {
    40  		ok = false
    41  	}
    42  	return
    43  }
    44  
    45  func (ss *ServerTerminal) Write(buf []byte) (n int, err error) {
    46  	return ss.Term.Write(buf)
    47  }
    48  
    49  // ReadLine returns a line of input from the terminal.
    50  func (ss *ServerTerminal) ReadLine() (line string, err error) {
    51  	for {
    52  		if line, err = ss.Term.ReadLine(); err == nil {
    53  			return
    54  		}
    55  
    56  		req, ok := err.(ChannelRequest)
    57  		if !ok {
    58  			return
    59  		}
    60  
    61  		ok = false
    62  		switch req.Request {
    63  		case "pty-req":
    64  			var width, height int
    65  			width, height, ok = parsePtyRequest(req.Payload)
    66  			ss.Term.SetSize(width, height)
    67  		case "shell":
    68  			ok = true
    69  			if len(req.Payload) > 0 {
    70  				// We don't accept any commands, only the default shell.
    71  				ok = false
    72  			}
    73  		case "env":
    74  			ok = true
    75  		}
    76  		if req.WantReply {
    77  			ss.Channel.AckRequest(ok)
    78  		}
    79  	}
    80  	panic("unreachable")
    81  }