blob: f8421490588ad1c4a43727c1d6ba5d9ef7de6231 [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
Eric Andersen50d63601999-11-09 01:47:36 +000036#ifdef BB_FEATURE_USE_TERMIOS
Eric Andersenf5a38381999-10-19 22:26:25 +000037
Erik Andersena6c75222000-04-18 00:00:52 +000038#include <termio.h>
Eric Andersen3cf52d11999-10-12 22:26:06 +000039
Erik Andersene49d5ec2000-02-08 19:58:47 +000040FILE *cin;
Erik Andersena6c75222000-04-18 00:00:52 +000041/* sparc and other have broken termios support: use old termio handling. */
42struct termio initial_settings, new_settings;
Eric Andersen3cf52d11999-10-12 22:26:06 +000043
Erik Andersene49d5ec2000-02-08 19:58:47 +000044void gotsig(int sig)
45{
Erik Andersena6c75222000-04-18 00:00:52 +000046 ioctl(fileno(cin), TCSETAF, &initial_settings);
Erik Andersene49d5ec2000-02-08 19:58:47 +000047 fprintf(stdout, "\n");
48 exit(TRUE);
49}
Eric Andersen3cf52d11999-10-12 22:26:06 +000050#endif
Eric Andersencc8ed391999-10-05 16:24:54 +000051
Eric Andersen50d63601999-11-09 01:47:36 +000052
53
Erik Andersene49d5ec2000-02-08 19:58:47 +000054#define TERMINAL_WIDTH 79 /* not 80 in case terminal has linefold bug */
Eric Andersen50d63601999-11-09 01:47:36 +000055#define TERMINAL_HEIGHT 24
56
57
Eric Andersen96bcfd31999-11-12 01:30:18 +000058#if defined BB_FEATURE_AUTOWIDTH
Eric Andersen50d63601999-11-09 01:47:36 +000059static int terminal_width = 0, terminal_height = 0;
60#else
61#define terminal_width TERMINAL_WIDTH
62#define terminal_height TERMINAL_HEIGHT
63#endif
64
65
66
Eric Andersen4bea32a1999-10-06 00:30:51 +000067extern int more_main(int argc, char **argv)
Eric Andersencc8ed391999-10-05 16:24:54 +000068{
Erik Andersene49d5ec2000-02-08 19:58:47 +000069 int c, lines = 0, input = 0;
70 int next_page = 0;
71 struct stat st;
72 FILE *file;
73
Eric Andersen50d63601999-11-09 01:47:36 +000074#ifdef BB_FEATURE_AUTOWIDTH
Erik Andersene49d5ec2000-02-08 19:58:47 +000075 struct winsize win = { 0, 0 };
Eric Andersen50d63601999-11-09 01:47:36 +000076#endif
Eric Andersen4bea32a1999-10-06 00:30:51 +000077
Erik Andersene49d5ec2000-02-08 19:58:47 +000078 argc--;
Eric Andersen4bea32a1999-10-06 00:30:51 +000079 argv++;
Eric Andersen4bea32a1999-10-06 00:30:51 +000080
Erik Andersene49d5ec2000-02-08 19:58:47 +000081 if (argc > 0
82 && (strcmp(*argv, "--help") == 0 || strcmp(*argv, "-h") == 0)) {
83 usage(more_usage);
84 }
85 do {
86 if (argc == 0) {
87 file = stdin;
88 } else
89 file = fopen(*argv, "r");
90
91 if (file == NULL) {
92 perror(*argv);
93 exit(FALSE);
94 }
95 fstat(fileno(file), &st);
96
97#ifdef BB_FEATURE_USE_TERMIOS
98 cin = fopen("/dev/tty", "r");
99 if (!cin)
100 cin = fopen("/dev/console", "r");
Erik Andersene49d5ec2000-02-08 19:58:47 +0000101 ioctl(fileno(cin), TCGETA, &initial_settings);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000102 new_settings = initial_settings;
103 new_settings.c_lflag &= ~ICANON;
104 new_settings.c_lflag &= ~ECHO;
Erik Andersena6c75222000-04-18 00:00:52 +0000105 ioctl(fileno(cin), TCSETAF, &new_settings);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000106
107#ifdef BB_FEATURE_AUTOWIDTH
108 ioctl(fileno(stdout), TIOCGWINSZ, &win);
109 if (win.ws_row > 4)
110 terminal_height = win.ws_row - 2;
111 if (win.ws_col > 0)
112 terminal_width = win.ws_col - 1;
113#endif
114
115 (void) signal(SIGINT, gotsig);
116 (void) signal(SIGQUIT, gotsig);
117 (void) signal(SIGTERM, gotsig);
118
119#endif
120 while ((c = getc(file)) != EOF) {
121 if (next_page) {
122 int len = 0;
123
124 next_page = 0;
125 lines = 0;
126 len = fprintf(stdout, "--More-- ");
127 if (file != stdin) {
128 len += fprintf(stdout, "(%d%% of %ld bytes)",
129 (int) (100 *
130 ((double) ftell(file) /
131 (double) st.st_size)),
132 st.st_size);
133 }
134 len += fprintf(stdout, "%s",
135#ifdef BB_FEATURE_USE_TERMIOS
136 ""
137#else
138 "\n"
139#endif
140 );
141
142 fflush(stdout);
143 input = getc(cin);
144
145#ifdef BB_FEATURE_USE_TERMIOS
146 /* Erase the "More" message */
147 while (--len >= 0)
148 putc('\b', stdout);
149 while (++len <= terminal_width)
150 putc(' ', stdout);
151 while (--len >= 0)
152 putc('\b', stdout);
153 fflush(stdout);
154#endif
155
156 }
157 if (c == '\n') {
158 switch (input) {
159 case 'q':
160 goto end;
161 case '\n':
162 /* increment by just one line if we are at
163 * the end of this line*/
164 next_page = 1;
165 break;
166 }
167 if (++lines == terminal_height)
168 next_page = 1;
169 }
170 putc(c, stdout);
171 }
172 fclose(file);
173 fflush(stdout);
174
175 argv++;
176 } while (--argc > 0);
177 end:
178#ifdef BB_FEATURE_USE_TERMIOS
179 gotsig(0);
180#endif
181 exit(TRUE);
182}