pager.c revision 72621
138451Smsmith/*- 238451Smsmith * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> 338451Smsmith * All rights reserved. 438451Smsmith * 538451Smsmith * Redistribution and use in source and binary forms, with or without 638451Smsmith * modification, are permitted provided that the following conditions 738451Smsmith * are met: 838451Smsmith * 1. Redistributions of source code must retain the above copyright 938451Smsmith * notice, this list of conditions and the following disclaimer. 1038451Smsmith * 2. Redistributions in binary form must reproduce the above copyright 1138451Smsmith * notice, this list of conditions and the following disclaimer in the 1238451Smsmith * documentation and/or other materials provided with the distribution. 1338451Smsmith * 1438451Smsmith * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1538451Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1638451Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1738451Smsmith * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1838451Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1938451Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2038451Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2138451Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2238451Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2338451Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2438451Smsmith * SUCH DAMAGE. 2538451Smsmith * 2650476Speter * $FreeBSD: head/lib/libstand/pager.c 72621 2001-02-18 04:51:47Z kris $ 2738451Smsmith */ 2838451Smsmith/* 2938451Smsmith * Simple paged-output and paged-viewing functions 3038451Smsmith */ 3138451Smsmith 3238451Smsmith#include "stand.h" 3338451Smsmith#include <string.h> 3438451Smsmith 3538451Smsmithstatic int p_maxlines = -1; 3638451Smsmithstatic int p_freelines; 3738451Smsmith 3838451Smsmithstatic char *pager_prompt1 = " --more-- <space> page down <enter> line down <q> quit "; 3938451Smsmithstatic char *pager_blank = " "; 4038451Smsmith 4138451Smsmith/* 4238451Smsmith * 'open' the pager 4338451Smsmith */ 4438451Smsmithvoid 4538451Smsmithpager_open(void) 4638451Smsmith{ 4738451Smsmith int nlines; 4838451Smsmith char *cp, *lp; 4938451Smsmith 5038451Smsmith nlines = 24; /* sensible default */ 5138451Smsmith if ((cp = getenv("LINES")) != NULL) { 5238451Smsmith nlines = strtol(cp, &lp, 0); 5338451Smsmith } 5438451Smsmith 5538451Smsmith p_maxlines = nlines - 1; 5638451Smsmith if (p_maxlines < 1) 5738451Smsmith p_maxlines = 1; 5838451Smsmith p_freelines = p_maxlines; 5938451Smsmith} 6038451Smsmith 6138451Smsmith/* 6238451Smsmith * 'close' the pager 6338451Smsmith */ 6438451Smsmithvoid 6538451Smsmithpager_close(void) 6638451Smsmith{ 6738451Smsmith p_maxlines = -1; 6838451Smsmith} 6938451Smsmith 7038451Smsmith/* 7138451Smsmith * Emit lines to the pager; may not return until the user 7238451Smsmith * has responded to the prompt. 7338451Smsmith * 7438451Smsmith * Will return nonzero if the user enters 'q' or 'Q' at the prompt. 7538451Smsmith * 7638451Smsmith * XXX note that this watches outgoing newlines (and eats them), but 7738451Smsmith * does not handle wrap detection (req. count of columns). 7838451Smsmith */ 7938451Smsmith 8038451Smsmithint 8138451Smsmithpager_output(const char *cp) 8238451Smsmith{ 8338451Smsmith int action; 8438451Smsmith 8538451Smsmith if (cp == NULL) 8638451Smsmith return(0); 8738451Smsmith 8838451Smsmith for (;;) { 8938451Smsmith if (*cp == 0) 9038451Smsmith return(0); 9138451Smsmith 9238451Smsmith putchar(*cp); /* always emit character */ 9338451Smsmith 9438451Smsmith if (*(cp++) == '\n') { /* got a newline? */ 9538451Smsmith p_freelines--; 9638451Smsmith if (p_freelines <= 0) { 9772621Skris printf("%s", pager_prompt1); 9838451Smsmith action = 0; 9938451Smsmith while (action == 0) { 10038451Smsmith switch(getchar()) { 10138451Smsmith case '\r': 10238451Smsmith case '\n': 10338451Smsmith p_freelines = 1; 10438451Smsmith action = 1; 10538451Smsmith break; 10638451Smsmith case ' ': 10738451Smsmith p_freelines = p_maxlines; 10838451Smsmith action = 1; 10938451Smsmith break; 11038451Smsmith case 'q': 11138451Smsmith case 'Q': 11238451Smsmith action = 2; 11338451Smsmith break; 11438451Smsmith default: 11538451Smsmith break; 11638451Smsmith } 11738451Smsmith } 11838451Smsmith printf("\r%s\r", pager_blank); 11938451Smsmith if (action == 2) 12038451Smsmith return(1); 12138451Smsmith } 12238451Smsmith } 12338451Smsmith } 12438451Smsmith} 12538451Smsmith 12638451Smsmith/* 12738451Smsmith * Display from (fd). 12838451Smsmith */ 12938451Smsmithint 13039468Smsmithpager_file(const char *fname) 13138451Smsmith{ 13238451Smsmith char buf[80]; 13338451Smsmith size_t hmuch; 13438451Smsmith int fd; 13538451Smsmith int result; 13638451Smsmith 13738451Smsmith if ((fd = open(fname, O_RDONLY)) == -1) { 13838451Smsmith printf("can't open '%s': %s\n", fname, strerror(errno)); 13938451Smsmith return(-1); 14038451Smsmith } 14138451Smsmith 14238451Smsmith for (;;) { 14338451Smsmith hmuch = read(fd, buf, sizeof(buf) - 1); 14438451Smsmith if (hmuch == -1) { 14538451Smsmith result = -1; 14638451Smsmith break; 14738451Smsmith } 14838451Smsmith if (hmuch == 0) { 14938451Smsmith result = 0; 15038451Smsmith break; 15138451Smsmith } 15238451Smsmith buf[hmuch] = 0; 15338451Smsmith if (pager_output(buf)) { 15438451Smsmith result = 1; 15538451Smsmith break; 15638451Smsmith } 15738451Smsmith } 15838451Smsmith close(fd); 15938451Smsmith return(result); 16038451Smsmith} 161