blob: 909ed286be15c61df793b42882fb5917fb88c6a0 [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;
Erik Andersene90f4042000-04-21 21:53:58 +0000112 new_settings.c_cc[VMIN] = 1;
113 new_settings.c_cc[VTIME] = 0;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000114 new_settings.c_lflag &= ~ICANON;
115 new_settings.c_lflag &= ~ECHO;
Erik Andersen1d1d9502000-04-21 01:26:49 +0000116 setTermSettings(fileno(cin), &new_settings);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000117
118#ifdef BB_FEATURE_AUTOWIDTH
119 ioctl(fileno(stdout), TIOCGWINSZ, &win);
120 if (win.ws_row > 4)
121 terminal_height = win.ws_row - 2;
122 if (win.ws_col > 0)
123 terminal_width = win.ws_col - 1;
124#endif
125
126 (void) signal(SIGINT, gotsig);
127 (void) signal(SIGQUIT, gotsig);
128 (void) signal(SIGTERM, gotsig);
129
130#endif
131 while ((c = getc(file)) != EOF) {
132 if (next_page) {
133 int len = 0;
134
135 next_page = 0;
136 lines = 0;
137 len = fprintf(stdout, "--More-- ");
138 if (file != stdin) {
139 len += fprintf(stdout, "(%d%% of %ld bytes)",
140 (int) (100 *
141 ((double) ftell(file) /
142 (double) st.st_size)),
143 st.st_size);
144 }
145 len += fprintf(stdout, "%s",
146#ifdef BB_FEATURE_USE_TERMIOS
147 ""
148#else
149 "\n"
150#endif
151 );
152
153 fflush(stdout);
154 input = getc(cin);
155
156#ifdef BB_FEATURE_USE_TERMIOS
157 /* Erase the "More" message */
158 while (--len >= 0)
159 putc('\b', stdout);
160 while (++len <= terminal_width)
161 putc(' ', stdout);
162 while (--len >= 0)
163 putc('\b', stdout);
164 fflush(stdout);
165#endif
166
167 }
168 if (c == '\n') {
169 switch (input) {
170 case 'q':
171 goto end;
172 case '\n':
173 /* increment by just one line if we are at
174 * the end of this line*/
175 next_page = 1;
176 break;
177 }
178 if (++lines == terminal_height)
179 next_page = 1;
180 }
181 putc(c, stdout);
182 }
183 fclose(file);
184 fflush(stdout);
185
186 argv++;
187 } while (--argc > 0);
188 end:
189#ifdef BB_FEATURE_USE_TERMIOS
190 gotsig(0);
191#endif
192 exit(TRUE);
193}