1 /* $NetBSD: pager.c,v 1.1 2006/04/07 14:21:29 cherry Exp $ */ 2 3 /*- 4 * Copyright (c) 1998 Michael Smith <msmith@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