Home | History | Annotate | Line # | Download | only in common
pager.c revision 1.1
      1 /*	$NetBSD: pager.c,v 1.1 2006/04/07 14:21:29 cherry 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 
     36 #include <bootstrap.h>
     37 
     38 static int	p_maxlines = -1;
     39 static int	p_freelines;
     40 
     41 static char *pager_prompt1 = " --more--  <space> page down <enter> line down <q> quit ";
     42 static char *pager_blank   = "                                                        ";
     43 
     44 /*
     45  * 'open' the pager
     46  */
     47 void
     48 pager_open(void)
     49 {
     50     int		nlines;
     51     char	*cp, *lp;
     52 
     53     nlines = 24;		/* sensible default */
     54     if ((cp = getenv("LINES")) != NULL) {
     55 	nlines = strtol(cp, &lp, 0);
     56     }
     57 
     58     p_maxlines = nlines - 1;
     59     if (p_maxlines < 1)
     60 	p_maxlines = 1;
     61     p_freelines = p_maxlines;
     62 }
     63 
     64 /*
     65  * 'close' the pager
     66  */
     67 void
     68 pager_close(void)
     69 {
     70     p_maxlines = -1;
     71 }
     72 
     73 /*
     74  * Emit lines to the pager; may not return until the user
     75  * has responded to the prompt.
     76  *
     77  * Will return nonzero if the user enters 'q' or 'Q' at the prompt.
     78  *
     79  * XXX note that this watches outgoing newlines (and eats them), but
     80  *     does not handle wrap detection (req. count of columns).
     81  */
     82 
     83 int
     84 pager_output(const char *cp)
     85 {
     86     int		action;
     87 
     88     if (cp == NULL)
     89 	return(0);
     90 
     91     for (;;) {
     92 	if (*cp == 0)
     93 	    return(0);
     94 
     95 	putchar(*cp);			/* always emit character */
     96 
     97 	if (*(cp++) == '\n') {		/* got a newline? */
     98 	    p_freelines--;
     99 	    if (p_freelines <= 0) {
    100 		printf("%s", pager_prompt1);
    101 		action = 0;
    102 		while (action == 0) {
    103 		    switch(getchar()) {
    104 		    case '\r':
    105 		    case '\n':
    106 			p_freelines = 1;
    107 			action = 1;
    108 			break;
    109 		    case ' ':
    110 			p_freelines = p_maxlines;
    111 			action = 1;
    112 			break;
    113 		    case 'q':
    114 		    case 'Q':
    115 			action = 2;
    116 			break;
    117 		    default:
    118 			break;
    119 		    }
    120 		}
    121 		printf("\r%s\r", pager_blank);
    122 		if (action == 2)
    123 		    return(1);
    124 	    }
    125 	}
    126     }
    127 }
    128 
    129 /*
    130  * Display from (fd).
    131  */
    132 int
    133 pager_file(const char *fname)
    134 {
    135     char	buf[80];
    136     size_t	hmuch;
    137     int		fd;
    138     int		result;
    139 
    140     if ((fd = open(fname, O_RDONLY)) == -1) {
    141 	printf("can't open '%s': %s\n", fname, strerror(errno));
    142 	return(-1);
    143     }
    144 
    145     for (;;) {
    146 	hmuch = read(fd, buf, sizeof(buf) - 1);
    147 	if (hmuch == -1) {
    148 	    result = -1;
    149 	    break;
    150 	}
    151 	if (hmuch == 0) {
    152 	    result = 0;
    153 	    break;
    154 	}
    155 	buf[hmuch] = 0;
    156 	if (pager_output(buf)) {
    157 	    result = 1;
    158 	    break;
    159 	}
    160     }
    161     close(fd);
    162     return(result);
    163 }
    164