Home | History | Annotate | Line # | Download | only in common
      1 /*	$NetBSD: pager.c,v 1.2 2009/07/20 04:59:03 kiyohara Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1998 Michael Smith <msmith (at) freebsd.org>
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 /*
     29  * Simple paged-output and paged-viewing functions
     30  */
     31 
     32 #include <sys/cdefs.h>
     33 
     34 #include "lib/libsa/stand.h"
     35 #include "lib/libsa/loadfile.h"
     36 
     37 #include <bootstrap.h>
     38 
     39 static int	p_maxlines = -1;
     40 static int	p_freelines;
     41 
     42 static char *pager_prompt1 = " --more--  <space> page down <enter> line down <q> quit ";
     43 static char *pager_blank   = "                                                        ";
     44 
     45 /*
     46  * 'open' the pager
     47  */
     48 void
     49 pager_open(void)
     50 {
     51     int		nlines;
     52     char	*cp, *lp;
     53 
     54     nlines = 24;		/* sensible default */
     55     if ((cp = getenv("LINES")) != NULL) {
     56 	nlines = strtol(cp, &lp, 0);
     57     }
     58 
     59     p_maxlines = nlines - 1;
     60     if (p_maxlines < 1)
     61 	p_maxlines = 1;
     62     p_freelines = p_maxlines;
     63 }
     64 
     65 /*
     66  * 'close' the pager
     67  */
     68 void
     69 pager_close(void)
     70 {
     71     p_maxlines = -1;
     72 }
     73 
     74 /*
     75  * Emit lines to the pager; may not return until the user
     76  * has responded to the prompt.
     77  *
     78  * Will return nonzero if the user enters 'q' or 'Q' at the prompt.
     79  *
     80  * XXX note that this watches outgoing newlines (and eats them), but
     81  *     does not handle wrap detection (req. count of columns).
     82  */
     83 
     84 int
     85 pager_output(const char *cp)
     86 {
     87     int		action;
     88 
     89     if (cp == NULL)
     90 	return(0);
     91 
     92     for (;;) {
     93 	if (*cp == 0)
     94 	    return(0);
     95 
     96 	putchar(*cp);			/* always emit character */
     97 
     98 	if (*(cp++) == '\n') {		/* got a newline? */
     99 	    p_freelines--;
    100 	    if (p_freelines <= 0) {
    101 		printf("%s", pager_prompt1);
    102 		action = 0;
    103 		while (action == 0) {
    104 		    switch(getchar()) {
    105 		    case '\r':
    106 		    case '\n':
    107 			p_freelines = 1;
    108 			action = 1;
    109 			break;
    110 		    case ' ':
    111 			p_freelines = p_maxlines;
    112 			action = 1;
    113 			break;
    114 		    case 'q':
    115 		    case 'Q':
    116 			action = 2;
    117 			break;
    118 		    default:
    119 			break;
    120 		    }
    121 		}
    122 		printf("\r%s\r", pager_blank);
    123 		if (action == 2)
    124 		    return(1);
    125 	    }
    126 	}
    127     }
    128 }
    129 
    130 /*
    131  * Display from (fd).
    132  */
    133 int
    134 pager_file(const char *fname)
    135 {
    136     char	buf[80];
    137     size_t	hmuch;
    138     int		fd;
    139     int		result;
    140 
    141     if ((fd = open(fname, O_RDONLY)) == -1) {
    142 	printf("can't open '%s': %s\n", fname, strerror(errno));
    143 	return(-1);
    144     }
    145 
    146     for (;;) {
    147 	hmuch = read(fd, buf, sizeof(buf) - 1);
    148 	if (hmuch == -1) {
    149 	    result = -1;
    150 	    break;
    151 	}
    152 	if (hmuch == 0) {
    153 	    result = 0;
    154 	    break;
    155 	}
    156 	buf[hmuch] = 0;
    157 	if (pager_output(buf)) {
    158 	    result = 1;
    159 	    break;
    160 	}
    161     }
    162     close(fd);
    163     return(result);
    164 }
    165