blob: 30d2757cd240eab68b1991e4894e0b92947075c2 [file] [log] [blame]
Erik Andersene49d5ec2000-02-08 19:58:47 +00001/* vi: set sw=4 ts=4: */
Eric Andersen4bea32a1999-10-06 00:30:51 +00002/*
3 * Mini more implementation for busybox
4 *
Eric Andersenc4996011999-10-20 22:08:37 +00005 *
Eric Andersen96bcfd31999-11-12 01:30:18 +00006 * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>.
7 *
8 * Latest version blended together by Erik Andersen <andersen@lineo.com>,
9 * based on the original more implementation by Bruce, and code from the
10 * Debian boot-floppies team.
Eric Andersen4bea32a1999-10-06 00:30:51 +000011 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
26 */
27
Eric Andersencc8ed391999-10-05 16:24:54 +000028#include "internal.h"
29#include <stdio.h>
Eric Andersenf5a38381999-10-19 22:26:25 +000030#include <fcntl.h>
Eric Andersen4bea32a1999-10-06 00:30:51 +000031#include <signal.h>
Eric Andersen50d63601999-11-09 01:47:36 +000032#include <sys/ioctl.h>
Eric Andersen3cf52d11999-10-12 22:26:06 +000033
Eric Andersend73dc5b1999-11-10 23:13:02 +000034static const char more_usage[] = "more [file ...]\n";
Eric Andersencc8ed391999-10-05 16:24:54 +000035
Erik Andersen1d1d9502000-04-21 01:26:49 +000036/* ED: sparc termios is broken: revert back to old termio handling. */
Eric Andersen50d63601999-11-09 01:47:36 +000037#ifdef BB_FEATURE_USE_TERMIOS
Eric Andersenf5a38381999-10-19 22:26:25 +000038
Erik Andersen1d1d9502000-04-21 01:26:49 +000039#if #cpu(sparc)
40# include <termio.h>
41# define termios termio
42# define setTermSettings(fd,argp) ioctl(fd,TCSETAF,argp)
43# define getTermSettings(fd,argp) ioctl(fd,TCGETA,argp)
44#else
45# include <termios.h>
46# define setTermSettings(fd,argp) tcsetattr(fd,TCSANOW,argp)
47# define getTermSettings(fd,argp) tcgetattr(fd, argp);
48#endif
Eric Andersen3cf52d11999-10-12 22:26:06 +000049
Erik Andersene49d5ec2000-02-08 19:58:47 +000050FILE *cin;
Erik Andersen4f3f7572000-04-28 00:18:56 +000051
Erik Andersen1d1d9502000-04-21 01:26:49 +000052struct termios initial_settings, new_settings;
Eric Andersen3cf52d11999-10-12 22:26:06 +000053
Erik Andersene49d5ec2000-02-08 19:58:47 +000054void gotsig(int sig)
55{
Erik Andersen1d1d9502000-04-21 01:26:49 +000056 setTermSettings(fileno(cin), &initial_settings);
Erik Andersene49d5ec2000-02-08 19:58:47 +000057 fprintf(stdout, "\n");
58 exit(TRUE);
59}
Eric Andersen3cf52d11999-10-12 22:26:06 +000060#endif
Eric Andersencc8ed391999-10-05 16:24:54 +000061
Eric Andersen50d63601999-11-09 01:47:36 +000062
63
Erik Andersene49d5ec2000-02-08 19:58:47 +000064#define TERMINAL_WIDTH 79 /* not 80 in case terminal has linefold bug */
Eric Andersen50d63601999-11-09 01:47:36 +000065#define TERMINAL_HEIGHT 24
66
67
Eric Andersen96bcfd31999-11-12 01:30:18 +000068#if defined BB_FEATURE_AUTOWIDTH
Erik Andersen4f3f7572000-04-28 00:18:56 +000069#ifdef BB_FEATURE_USE_TERMIOS
70static int terminal_width = 0;
71#endif
72static int terminal_height = 0;
Eric Andersen50d63601999-11-09 01:47:36 +000073#else
74#define terminal_width TERMINAL_WIDTH
75#define terminal_height TERMINAL_HEIGHT
76#endif
77
78
79
Eric Andersen4bea32a1999-10-06 00:30:51 +000080extern int more_main(int argc, char **argv)
Eric Andersencc8ed391999-10-05 16:24:54 +000081{
Erik Andersene49d5ec2000-02-08 19:58:47 +000082 int c, lines = 0, input = 0;
83 int next_page = 0;
84 struct stat st;
85 FILE *file;
86
Erik Andersen4f3f7572000-04-28 00:18:56 +000087#if defined BB_FEATURE_AUTOWIDTH && defined BB_FEATURE_USE_TERMIOS
Erik Andersene49d5ec2000-02-08 19:58:47 +000088 struct winsize win = { 0, 0 };
Eric Andersen50d63601999-11-09 01:47:36 +000089#endif
Eric Andersen4bea32a1999-10-06 00:30:51 +000090
Erik Andersene49d5ec2000-02-08 19:58:47 +000091 argc--;
Eric Andersen4bea32a1999-10-06 00:30:51 +000092 argv++;
Eric Andersen4bea32a1999-10-06 00:30:51 +000093
Erik Andersene49d5ec2000-02-08 19:58:47 +000094 if (argc > 0
95 && (strcmp(*argv, "--help") == 0 || strcmp(*argv, "-h") == 0)) {
96 usage(more_usage);
97 }
98 do {
99 if (argc == 0) {
100 file = stdin;
101 } else
102 file = fopen(*argv, "r");
103
104 if (file == NULL) {
105 perror(*argv);
106 exit(FALSE);
107 }
108 fstat(fileno(file), &st);
109
110#ifdef BB_FEATURE_USE_TERMIOS
111 cin = fopen("/dev/tty", "r");
112 if (!cin)
113 cin = fopen("/dev/console", "r");
Erik Andersen1d1d9502000-04-21 01:26:49 +0000114 getTermSettings(fileno(cin), &initial_settings);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000115 new_settings = initial_settings;
Erik Andersene90f4042000-04-21 21:53:58 +0000116 new_settings.c_cc[VMIN] = 1;
117 new_settings.c_cc[VTIME] = 0;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000118 new_settings.c_lflag &= ~ICANON;
119 new_settings.c_lflag &= ~ECHO;
Erik Andersen1d1d9502000-04-21 01:26:49 +0000120 setTermSettings(fileno(cin), &new_settings);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000121
122#ifdef BB_FEATURE_AUTOWIDTH
123 ioctl(fileno(stdout), TIOCGWINSZ, &win);
124 if (win.ws_row > 4)
125 terminal_height = win.ws_row - 2;
126 if (win.ws_col > 0)
127 terminal_width = win.ws_col - 1;
128#endif
129
130 (void) signal(SIGINT, gotsig);
131 (void) signal(SIGQUIT, gotsig);
132 (void) signal(SIGTERM, gotsig);
133
134#endif
135 while ((c = getc(file)) != EOF) {
136 if (next_page) {
137 int len = 0;
138
139 next_page = 0;
140 lines = 0;
141 len = fprintf(stdout, "--More-- ");
142 if (file != stdin) {
143 len += fprintf(stdout, "(%d%% of %ld bytes)",
144 (int) (100 *
145 ((double) ftell(file) /
146 (double) st.st_size)),
147 st.st_size);
148 }
149 len += fprintf(stdout, "%s",
150#ifdef BB_FEATURE_USE_TERMIOS
151 ""
152#else
153 "\n"
154#endif
155 );
156
157 fflush(stdout);
Erik Andersen4f3f7572000-04-28 00:18:56 +0000158#ifdef BB_FEATURE_USE_TERMIOS
Erik Andersene49d5ec2000-02-08 19:58:47 +0000159 input = getc(cin);
Erik Andersen4f3f7572000-04-28 00:18:56 +0000160#else
161 input = getc(stdin);
162#endif
Erik Andersene49d5ec2000-02-08 19:58:47 +0000163
164#ifdef BB_FEATURE_USE_TERMIOS
165 /* Erase the "More" message */
166 while (--len >= 0)
167 putc('\b', stdout);
168 while (++len <= terminal_width)
169 putc(' ', stdout);
170 while (--len >= 0)
171 putc('\b', stdout);
172 fflush(stdout);
173#endif
174
175 }
176 if (c == '\n') {
177 switch (input) {
178 case 'q':
179 goto end;
180 case '\n':
181 /* increment by just one line if we are at
182 * the end of this line*/
183 next_page = 1;
184 break;
185 }
186 if (++lines == terminal_height)
187 next_page = 1;
188 }
189 putc(c, stdout);
190 }
191 fclose(file);
192 fflush(stdout);
193
194 argv++;
195 } while (--argc > 0);
196 end:
197#ifdef BB_FEATURE_USE_TERMIOS
198 gotsig(0);
199#endif
200 exit(TRUE);
201}