blob: 20aa37095a416e4abf50c7b359b83b328196d674 [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 Andersen1d1d9502000-04-21 01:26:49 +000051struct termios initial_settings, new_settings;
Eric Andersen3cf52d11999-10-12 22:26:06 +000052
Erik Andersene49d5ec2000-02-08 19:58:47 +000053void gotsig(int sig)
54{
Erik Andersen1d1d9502000-04-21 01:26:49 +000055 setTermSettings(fileno(cin), &initial_settings);
Erik Andersene49d5ec2000-02-08 19:58:47 +000056 fprintf(stdout, "\n");
57 exit(TRUE);
58}
Eric Andersen3cf52d11999-10-12 22:26:06 +000059#endif
Eric Andersencc8ed391999-10-05 16:24:54 +000060
Eric Andersen50d63601999-11-09 01:47:36 +000061
62
Erik Andersene49d5ec2000-02-08 19:58:47 +000063#define TERMINAL_WIDTH 79 /* not 80 in case terminal has linefold bug */
Eric Andersen50d63601999-11-09 01:47:36 +000064#define TERMINAL_HEIGHT 24
65
66
Eric Andersen96bcfd31999-11-12 01:30:18 +000067#if defined BB_FEATURE_AUTOWIDTH
Eric Andersen50d63601999-11-09 01:47:36 +000068static int terminal_width = 0, terminal_height = 0;
69#else
70#define terminal_width TERMINAL_WIDTH
71#define terminal_height TERMINAL_HEIGHT
72#endif
73
74
75
Eric Andersen4bea32a1999-10-06 00:30:51 +000076extern int more_main(int argc, char **argv)
Eric Andersencc8ed391999-10-05 16:24:54 +000077{
Erik Andersene49d5ec2000-02-08 19:58:47 +000078 int c, lines = 0, input = 0;
79 int next_page = 0;
80 struct stat st;
81 FILE *file;
82
Eric Andersen50d63601999-11-09 01:47:36 +000083#ifdef BB_FEATURE_AUTOWIDTH
Erik Andersene49d5ec2000-02-08 19:58:47 +000084 struct winsize win = { 0, 0 };
Eric Andersen50d63601999-11-09 01:47:36 +000085#endif
Eric Andersen4bea32a1999-10-06 00:30:51 +000086
Erik Andersene49d5ec2000-02-08 19:58:47 +000087 argc--;
Eric Andersen4bea32a1999-10-06 00:30:51 +000088 argv++;
Eric Andersen4bea32a1999-10-06 00:30:51 +000089
Erik Andersene49d5ec2000-02-08 19:58:47 +000090 if (argc > 0
91 && (strcmp(*argv, "--help") == 0 || strcmp(*argv, "-h") == 0)) {
92 usage(more_usage);
93 }
94 do {
95 if (argc == 0) {
96 file = stdin;
97 } else
98 file = fopen(*argv, "r");
99
100 if (file == NULL) {
101 perror(*argv);
102 exit(FALSE);
103 }
104 fstat(fileno(file), &st);
105
106#ifdef BB_FEATURE_USE_TERMIOS
107 cin = fopen("/dev/tty", "r");
108 if (!cin)
109 cin = fopen("/dev/console", "r");
Erik Andersen1d1d9502000-04-21 01:26:49 +0000110 getTermSettings(fileno(cin), &initial_settings);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000111 new_settings = initial_settings;
112 new_settings.c_lflag &= ~ICANON;
113 new_settings.c_lflag &= ~ECHO;
Erik Andersen1d1d9502000-04-21 01:26:49 +0000114 setTermSettings(fileno(cin), &new_settings);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000115
116#ifdef BB_FEATURE_AUTOWIDTH
117 ioctl(fileno(stdout), TIOCGWINSZ, &win);
118 if (win.ws_row > 4)
119 terminal_height = win.ws_row - 2;
120 if (win.ws_col > 0)
121 terminal_width = win.ws_col - 1;
122#endif
123
124 (void) signal(SIGINT, gotsig);
125 (void) signal(SIGQUIT, gotsig);
126 (void) signal(SIGTERM, gotsig);
127
128#endif
129 while ((c = getc(file)) != EOF) {
130 if (next_page) {
131 int len = 0;
132
133 next_page = 0;
134 lines = 0;
135 len = fprintf(stdout, "--More-- ");
136 if (file != stdin) {
137 len += fprintf(stdout, "(%d%% of %ld bytes)",
138 (int) (100 *
139 ((double) ftell(file) /
140 (double) st.st_size)),
141 st.st_size);
142 }
143 len += fprintf(stdout, "%s",
144#ifdef BB_FEATURE_USE_TERMIOS
145 ""
146#else
147 "\n"
148#endif
149 );
150
151 fflush(stdout);
152 input = getc(cin);
153
154#ifdef BB_FEATURE_USE_TERMIOS
155 /* Erase the "More" message */
156 while (--len >= 0)
157 putc('\b', stdout);
158 while (++len <= terminal_width)
159 putc(' ', stdout);
160 while (--len >= 0)
161 putc('\b', stdout);
162 fflush(stdout);
163#endif
164
165 }
166 if (c == '\n') {
167 switch (input) {
168 case 'q':
169 goto end;
170 case '\n':
171 /* increment by just one line if we are at
172 * the end of this line*/
173 next_page = 1;
174 break;
175 }
176 if (++lines == terminal_height)
177 next_page = 1;
178 }
179 putc(c, stdout);
180 }
181 fclose(file);
182 fflush(stdout);
183
184 argv++;
185 } while (--argc > 0);
186 end:
187#ifdef BB_FEATURE_USE_TERMIOS
188 gotsig(0);
189#endif
190 exit(TRUE);
191}