github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/cmds/exp/ssh/utils_plan9.go (about)

     1  // Copyright 2022 the u-root 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  //go:build plan9
     6  // +build plan9
     7  
     8  package main
     9  
    10  import (
    11  	"fmt"
    12  	"io"
    13  	"log"
    14  	"os"
    15  	"path/filepath"
    16  	"strconv"
    17  )
    18  
    19  var (
    20  	defaultKeyFile    = filepath.Join(os.Getenv("home"), "lib/ssh/id_rsa")
    21  	defaultConfigFile = filepath.Join(os.Getenv("home"), "lib/ssh/config")
    22  
    23  	consctl *os.File
    24  )
    25  
    26  func init() {
    27  	// We have to hold consctl open so we can mess with raw mode.
    28  	var err error
    29  	consctl, err = os.OpenFile("/dev/consctl", os.O_WRONLY, 0755)
    30  	if err != nil {
    31  		log.Fatal(err)
    32  	}
    33  }
    34  
    35  // cleanup turns raw mode back off and closes consctl
    36  func cleanup(in *os.File) {
    37  	consctl.Write([]byte("rawoff"))
    38  	consctl.Close()
    39  }
    40  
    41  // raw enters raw mode
    42  func raw(in *os.File) (err error) {
    43  	_, err = consctl.Write([]byte("rawon"))
    44  	return
    45  }
    46  
    47  // cooked turns off raw mode
    48  func cooked() (err error) {
    49  	_, err = consctl.Write([]byte("rawoff"))
    50  	return
    51  }
    52  
    53  // readPassword prompts the user for a password.
    54  func readPassword(in *os.File, out io.Writer) (string, error) {
    55  	fmt.Fprintf(out, "Password: ")
    56  	raw(in)
    57  	cons, err := os.OpenFile("/dev/cons", os.O_RDWR, 0755)
    58  	if err != nil {
    59  		return "", err
    60  	}
    61  	defer cons.Close()
    62  	var pw []byte
    63  	for {
    64  		x := make([]byte, 1)
    65  		if _, err := cons.Read(x); err != nil {
    66  			cooked()
    67  			return "", err
    68  		}
    69  		// newline OR carriage return
    70  		if x[0] == '\n' || x[0] == 0x0d {
    71  			break
    72  		}
    73  		pw = append(pw, x[0])
    74  	}
    75  	cooked()
    76  	// output a newline so things look nice
    77  	fmt.Fprintf(out, "\n")
    78  	return string(pw), nil
    79  }
    80  
    81  // getSize reads the size of the terminal window.
    82  func getSize(in *os.File) (width, height int, err error) {
    83  	// If we're running vt, there are environment variables to read.
    84  	// If not, we'll just say 80x24
    85  	width, height = 80, 24
    86  	lines := os.Getenv("LINES")
    87  	cols := os.Getenv("COLS")
    88  	if i, err := strconv.Atoi(lines); err == nil {
    89  		height = i
    90  	}
    91  	if i, err := strconv.Atoi(cols); err == nil {
    92  		width = i
    93  	}
    94  	return
    95  }