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