pager.c revision 84221
1131826Sharti/*- 2131826Sharti * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> 3131826Sharti * All rights reserved. 4131826Sharti * 5131826Sharti * Redistribution and use in source and binary forms, with or without 6131826Sharti * modification, are permitted provided that the following conditions 7131826Sharti * are met: 8131826Sharti * 1. Redistributions of source code must retain the above copyright 9131826Sharti * notice, this list of conditions and the following disclaimer. 10131826Sharti * 2. Redistributions in binary form must reproduce the above copyright 11131826Sharti * notice, this list of conditions and the following disclaimer in the 12131826Sharti * documentation and/or other materials provided with the distribution. 13131826Sharti * 14131826Sharti * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15131826Sharti * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16131826Sharti * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17131826Sharti * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18131826Sharti * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19131826Sharti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20131826Sharti * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21131826Sharti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22131826Sharti * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23131826Sharti * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24131826Sharti * SUCH DAMAGE. 25131826Sharti */ 26131826Sharti/* 27131826Sharti * Simple paged-output and paged-viewing functions 28131826Sharti */ 29131826Sharti 30146539Sharti#include <sys/cdefs.h> 31131826Sharti__FBSDID("$FreeBSD: head/lib/libstand/pager.c 84221 2001-09-30 22:28:01Z dillon $"); 32131826Sharti 33131826Sharti#include "stand.h" 34131826Sharti#include <string.h> 35131826Sharti 36131826Shartistatic int p_maxlines = -1; 37131826Shartistatic int p_freelines; 38131826Sharti 39131826Shartistatic char *pager_prompt1 = " --more-- <space> page down <enter> line down <q> quit "; 40131826Shartistatic char *pager_blank = " "; 41131826Sharti 42131826Sharti/* 43131826Sharti * 'open' the pager 44131826Sharti */ 45131826Shartivoid 46131826Shartipager_open(void) 47131826Sharti{ 48131826Sharti int nlines; 49131826Sharti char *cp, *lp; 50131826Sharti 51131826Sharti nlines = 24; /* sensible default */ 52131826Sharti if ((cp = getenv("LINES")) != NULL) { 53131826Sharti nlines = strtol(cp, &lp, 0); 54131826Sharti } 55131826Sharti 56131826Sharti p_maxlines = nlines - 1; 57131826Sharti if (p_maxlines < 1) 58131826Sharti p_maxlines = 1; 59131826Sharti p_freelines = p_maxlines; 60131826Sharti} 61131826Sharti 62131826Sharti/* 63131826Sharti * 'close' the pager 64131826Sharti */ 65131826Shartivoid 66131826Shartipager_close(void) 67131826Sharti{ 68131826Sharti p_maxlines = -1; 69131826Sharti} 70131826Sharti 71131826Sharti/* 72131826Sharti * Emit lines to the pager; may not return until the user 73131826Sharti * has responded to the prompt. 74131826Sharti * 75131826Sharti * Will return nonzero if the user enters 'q' or 'Q' at the prompt. 76131826Sharti * 77131826Sharti * XXX note that this watches outgoing newlines (and eats them), but 78131826Sharti * does not handle wrap detection (req. count of columns). 79131826Sharti */ 80131826Sharti 81131826Shartiint 82131826Shartipager_output(const char *cp) 83131826Sharti{ 84131826Sharti int action; 85131826Sharti 86131826Sharti if (cp == NULL) 87131826Sharti return(0); 88131826Sharti 89131826Sharti for (;;) { 90131826Sharti if (*cp == 0) 91131826Sharti return(0); 92131826Sharti 93131826Sharti putchar(*cp); /* always emit character */ 94131826Sharti 95131826Sharti if (*(cp++) == '\n') { /* got a newline? */ 96131826Sharti p_freelines--; 97131826Sharti if (p_freelines <= 0) { 98131826Sharti printf("%s", pager_prompt1); 99131826Sharti action = 0; 100131826Sharti while (action == 0) { 101131826Sharti switch(getchar()) { 102131826Sharti case '\r': 103131826Sharti case '\n': 104131826Sharti p_freelines = 1; 105131826Sharti action = 1; 106131826Sharti break; 107131826Sharti case ' ': 108131826Sharti p_freelines = p_maxlines; 109131826Sharti action = 1; 110131826Sharti break; 111131826Sharti case 'q': 112131826Sharti case 'Q': 113131826Sharti action = 2; 114131826Sharti break; 115131826Sharti default: 116131826Sharti break; 117131826Sharti } 118131826Sharti } 119131826Sharti printf("\r%s\r", pager_blank); 120131826Sharti if (action == 2) 121131826Sharti return(1); 122131826Sharti } 123131826Sharti } 124131826Sharti } 125131826Sharti} 126131826Sharti 127131826Sharti/* 128131826Sharti * Display from (fd). 129131826Sharti */ 130131826Shartiint 131131826Shartipager_file(const char *fname) 132131826Sharti{ 133131826Sharti char buf[80]; 134131826Sharti size_t hmuch; 135131826Sharti int fd; 136131826Sharti int result; 137131826Sharti 138131826Sharti if ((fd = open(fname, O_RDONLY)) == -1) { 139131826Sharti printf("can't open '%s': %s\n", fname, strerror(errno)); 140131826Sharti return(-1); 141131826Sharti } 142131826Sharti 143131826Sharti for (;;) { 144131826Sharti hmuch = read(fd, buf, sizeof(buf) - 1); 145131826Sharti if (hmuch == -1) { 146131826Sharti result = -1; 147131826Sharti break; 148131826Sharti } 149131826Sharti if (hmuch == 0) { 150131826Sharti result = 0; 151131826Sharti break; 152131826Sharti } 153131826Sharti buf[hmuch] = 0; 154131826Sharti if (pager_output(buf)) { 155131826Sharti result = 1; 156131826Sharti break; 157131826Sharti } 158131826Sharti } 159131826Sharti close(fd); 160131826Sharti return(result); 161131826Sharti} 162131826Sharti