github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/cmds/exp/page/main.go (about)

     1  // Copyright 2012-2020 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  // Synopsis:
     6  //     page [file]
     7  //
     8  // Description:
     9  // page prints a page at a time to stdout from either stdin or a named file.
    10  // It stops every x rows, where x is the number of rows determined from gtty.
    11  // Single character commands tell it what to do next. Currently the only ones
    12  // are return and q.
    13  //
    14  // Options:
    15  package main
    16  
    17  import (
    18  	"bufio"
    19  	"fmt"
    20  	"io"
    21  	"log"
    22  	"os"
    23  
    24  	"github.com/u-root/u-root/pkg/termios"
    25  )
    26  
    27  func page(t *termios.TTYIO, r io.Reader, w io.Writer) error {
    28  	rows := int64(24)
    29  	if w, err := t.GetWinSize(); err != nil {
    30  		log.Printf("Could not get win size: %v; continuing assuming %d rows", err, rows)
    31  	} else {
    32  		rows = int64(w.Row)
    33  	}
    34  
    35  	l := int64(1)
    36  	scanner := bufio.NewScanner(r)
    37  	for {
    38  		cur := l
    39  		for {
    40  			if !scanner.Scan() {
    41  				return scanner.Err()
    42  			}
    43  			line := scanner.Text()
    44  			if _, err := fmt.Fprintf(w, "%s\r\n", string(line)); err != nil {
    45  				return err
    46  			}
    47  			cur++
    48  			if cur > l+rows {
    49  				break
    50  			}
    51  		}
    52  		if cur == l {
    53  			break
    54  		}
    55  		l = cur
    56  		if _, err := fmt.Fprintf(t, ":"); err != nil {
    57  			return err
    58  		}
    59  		var cmd [1]byte
    60  		if _, err := t.Read(cmd[:]); err != nil {
    61  			return err
    62  		}
    63  		switch cmd[0] {
    64  		default:
    65  			fmt.Printf("%q:unknown\n", cmd[0])
    66  		case '\n', ' ':
    67  		case 'q':
    68  			return nil
    69  		}
    70  		fmt.Fprintf(w, "\r")
    71  	}
    72  
    73  	return nil
    74  }
    75  
    76  func main() {
    77  	t, err := termios.New()
    78  	if err != nil {
    79  		log.Fatal(err)
    80  	}
    81  	in := os.Stdin
    82  
    83  	switch len(os.Args) {
    84  	case 1:
    85  	case 2:
    86  		f, err := os.Open(os.Args[1])
    87  		if err != nil {
    88  			log.Fatal(err)
    89  		}
    90  		in = f
    91  	default:
    92  		log.Fatal("Usage: page [file]")
    93  	}
    94  	c, err := t.Raw()
    95  	if err != nil {
    96  		log.Fatal(err)
    97  	}
    98  	defer func() {
    99  		if err := t.Set(c); err != nil {
   100  			log.Printf("Restoring modes failed; sorry (%v)", err)
   101  		}
   102  	}()
   103  	if err := page(t, in, os.Stdout); err != nil {
   104  		log.Fatal(err)
   105  	}
   106  }