blob: 7d0ddb8ece069c2007c3de8fd53edd7f1025f788 [file] [log] [blame]
Eric Andersen4bea32a1999-10-06 00:30:51 +00001/*
2 * Mini more implementation for busybox
3 *
Eric Andersenc4996011999-10-20 22:08:37 +00004 *
Eric Andersen96bcfd31999-11-12 01:30:18 +00005 * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>.
6 *
7 * Latest version blended together by Erik Andersen <andersen@lineo.com>,
8 * based on the original more implementation by Bruce, and code from the
9 * Debian boot-floppies team.
Eric Andersen4bea32a1999-10-06 00:30:51 +000010 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
Eric Andersen3cf52d11999-10-12 22:26:06 +000027
28/* Turning this off makes things a bit smaller (and less pretty) */
Eric Andersen50d63601999-11-09 01:47:36 +000029#define BB_FEATURE_USE_TERMIOS
30/* Turning this off makes things a bit smaller (and less pretty) */
31#define BB_FEATURE_AUTOWIDTH
Eric Andersen3cf52d11999-10-12 22:26:06 +000032
33
34
Eric Andersencc8ed391999-10-05 16:24:54 +000035#include "internal.h"
36#include <stdio.h>
Eric Andersenf5a38381999-10-19 22:26:25 +000037#include <fcntl.h>
Eric Andersen4bea32a1999-10-06 00:30:51 +000038#include <signal.h>
Eric Andersen50d63601999-11-09 01:47:36 +000039#include <sys/ioctl.h>
Eric Andersen3cf52d11999-10-12 22:26:06 +000040
Eric Andersend73dc5b1999-11-10 23:13:02 +000041static const char more_usage[] = "more [file ...]\n";
Eric Andersencc8ed391999-10-05 16:24:54 +000042
Eric Andersenf5a38381999-10-19 22:26:25 +000043/* ED: sparc termios is broken: revert back to old termio handling. */
Eric Andersen50d63601999-11-09 01:47:36 +000044#ifdef BB_FEATURE_USE_TERMIOS
Eric Andersenf5a38381999-10-19 22:26:25 +000045
Eric Andersenfbb39c81999-11-08 17:00:52 +000046#if #cpu(sparc)
Eric Andersenf5a38381999-10-19 22:26:25 +000047# define USE_OLD_TERMIO
48# include <termio.h>
Eric Andersenf5a38381999-10-19 22:26:25 +000049# define termios termio
50# define stty(fd,argp) ioctl(fd,TCSETAF,argp)
51#else
52# include <termios.h>
53# define stty(fd,argp) tcsetattr(fd,TCSANOW,argp)
54#endif
Eric Andersen3cf52d11999-10-12 22:26:06 +000055
56 FILE *cin;
57 struct termios initial_settings, new_settings;
58
59 void gotsig(int sig) {
Eric Andersenf5a38381999-10-19 22:26:25 +000060 stty(fileno(cin), &initial_settings);
Eric Andersen50d63601999-11-09 01:47:36 +000061 fprintf(stdout, "\n");
Eric Andersen3cf52d11999-10-12 22:26:06 +000062 exit( TRUE);
63 }
64#endif
Eric Andersencc8ed391999-10-05 16:24:54 +000065
Eric Andersen50d63601999-11-09 01:47:36 +000066
67
68#define TERMINAL_WIDTH 79 /* not 80 in case terminal has linefold bug */
69#define TERMINAL_HEIGHT 24
70
71
Eric Andersen96bcfd31999-11-12 01:30:18 +000072#if defined BB_FEATURE_AUTOWIDTH
Eric Andersen50d63601999-11-09 01:47:36 +000073static int terminal_width = 0, terminal_height = 0;
74#else
75#define terminal_width TERMINAL_WIDTH
76#define terminal_height TERMINAL_HEIGHT
77#endif
78
79
80
Eric Andersen4bea32a1999-10-06 00:30:51 +000081extern int more_main(int argc, char **argv)
Eric Andersencc8ed391999-10-05 16:24:54 +000082{
Eric Andersen21943ce1999-10-13 18:04:51 +000083 int c, lines=0, input=0;
Eric Andersenf5a38381999-10-19 22:26:25 +000084 int next_page=0;
Eric Andersen4bea32a1999-10-06 00:30:51 +000085 struct stat st;
Eric Andersenf5a38381999-10-19 22:26:25 +000086 FILE *file;
Eric Andersen50d63601999-11-09 01:47:36 +000087#ifdef BB_FEATURE_AUTOWIDTH
Eric Andersen96bcfd31999-11-12 01:30:18 +000088 struct winsize win = {0,0};
Eric Andersen50d63601999-11-09 01:47:36 +000089#endif
Eric Andersen4bea32a1999-10-06 00:30:51 +000090
Eric Andersen4bea32a1999-10-06 00:30:51 +000091 argc--;
92 argv++;
93
Eric Andersenfbb39c81999-11-08 17:00:52 +000094 if ( argc > 0 && (strcmp(*argv,"--help")==0 || strcmp(*argv,"-h")==0) ) {
95 usage (more_usage);
96 }
97 do {
Eric Andersenf5a38381999-10-19 22:26:25 +000098 if (argc==0) {
99 file = stdin;
100 }
101 else
Eric Andersen9d3aba71999-10-06 09:04:55 +0000102 file = fopen(*argv, "r");
Eric Andersenf5a38381999-10-19 22:26:25 +0000103
Eric Andersen4bea32a1999-10-06 00:30:51 +0000104 if (file == NULL) {
Eric Andersenef8b6c71999-10-20 08:05:35 +0000105 perror(*argv);
Eric Andersen3cf52d11999-10-12 22:26:06 +0000106 exit(FALSE);
Eric Andersencc8ed391999-10-05 16:24:54 +0000107 }
Eric Andersen4bea32a1999-10-06 00:30:51 +0000108 fstat(fileno(file), &st);
Eric Andersencc8ed391999-10-05 16:24:54 +0000109
Eric Andersen50d63601999-11-09 01:47:36 +0000110#ifdef BB_FEATURE_USE_TERMIOS
Eric Andersen3cf52d11999-10-12 22:26:06 +0000111 cin = fopen("/dev/tty", "r");
Eric Andersenf5a38381999-10-19 22:26:25 +0000112 if (!cin)
113 cin = fopen("/dev/console", "r");
114#ifdef USE_OLD_TERMIO
115 ioctl(fileno(cin),TCGETA,&initial_settings);
116#else
Eric Andersen3cf52d11999-10-12 22:26:06 +0000117 tcgetattr(fileno(cin),&initial_settings);
Eric Andersenf5a38381999-10-19 22:26:25 +0000118#endif
Eric Andersen3cf52d11999-10-12 22:26:06 +0000119 new_settings = initial_settings;
120 new_settings.c_lflag &= ~ICANON;
121 new_settings.c_lflag &= ~ECHO;
Eric Andersenf5a38381999-10-19 22:26:25 +0000122 stty(fileno(cin), &new_settings);
Eric Andersen50d63601999-11-09 01:47:36 +0000123
124#ifdef BB_FEATURE_AUTOWIDTH
125 ioctl(STDOUT_FILENO, TIOCGWINSZ, &win);
126 if (win.ws_row > 4)
127 terminal_height = win.ws_row - 2;
128 if (win.ws_col > 0)
129 terminal_width = win.ws_col - 1;
130#endif
131
Eric Andersen3cf52d11999-10-12 22:26:06 +0000132 (void) signal(SIGINT, gotsig);
Eric Andersenfbb39c81999-11-08 17:00:52 +0000133 (void) signal(SIGQUIT, gotsig);
134 (void) signal(SIGTERM, gotsig);
135
Eric Andersen3cf52d11999-10-12 22:26:06 +0000136#endif
Eric Andersen4bea32a1999-10-06 00:30:51 +0000137 while ((c = getc(file)) != EOF) {
138 if ( next_page ) {
139 int len=0;
140 next_page = 0;
141 lines=0;
Eric Andersenf5a38381999-10-19 22:26:25 +0000142 len = fprintf(stdout, "--More-- ");
143 if (file != stdin) {
144 len += fprintf(stdout, "(%d%% of %ld bytes)",
Eric Andersen4bea32a1999-10-06 00:30:51 +0000145 (int) (100*( (double) ftell(file) / (double) st.st_size )),
Eric Andersenf5a38381999-10-19 22:26:25 +0000146 st.st_size);
147 }
148 len += fprintf(stdout, "%s",
Eric Andersen50d63601999-11-09 01:47:36 +0000149#ifdef BB_FEATURE_USE_TERMIOS
Eric Andersen3cf52d11999-10-12 22:26:06 +0000150 ""
151#else
152 "\n"
153#endif
154 );
155
Eric Andersen4bea32a1999-10-06 00:30:51 +0000156 fflush(stdout);
Eric Andersenf5a38381999-10-19 22:26:25 +0000157 input = getc( cin);
Eric Andersen3cf52d11999-10-12 22:26:06 +0000158
Eric Andersen50d63601999-11-09 01:47:36 +0000159#ifdef BB_FEATURE_USE_TERMIOS
Eric Andersen3cf52d11999-10-12 22:26:06 +0000160 /* Erase the "More" message */
Eric Andersen50d63601999-11-09 01:47:36 +0000161 while(--len >= 0)
Eric Andersen4bea32a1999-10-06 00:30:51 +0000162 putc('\b', stdout);
Eric Andersen50d63601999-11-09 01:47:36 +0000163 while(++len <= terminal_width)
Eric Andersen9d3aba71999-10-06 09:04:55 +0000164 putc(' ', stdout);
Eric Andersen50d63601999-11-09 01:47:36 +0000165 while(--len >= 0)
Eric Andersen4bea32a1999-10-06 00:30:51 +0000166 putc('\b', stdout);
167 fflush(stdout);
Eric Andersencc8ed391999-10-05 16:24:54 +0000168#endif
Eric Andersen3cf52d11999-10-12 22:26:06 +0000169
Eric Andersen4bea32a1999-10-06 00:30:51 +0000170 }
Eric Andersen50d63601999-11-09 01:47:36 +0000171 if (c == '\n' ) {
172 switch(input) {
173 case 'q':
174 goto end;
175 case '\n':
176 /* increment by just one line if we are at
177 * the end of this line*/
178 next_page = 1;
179 break;
180 }
181 if ( ++lines == terminal_height )
182 next_page = 1;
183 }
Eric Andersen4bea32a1999-10-06 00:30:51 +0000184 putc(c, stdout);
Eric Andersencc8ed391999-10-05 16:24:54 +0000185 }
Eric Andersen4bea32a1999-10-06 00:30:51 +0000186 fclose(file);
187 fflush(stdout);
188
Eric Andersen4bea32a1999-10-06 00:30:51 +0000189 argv++;
Eric Andersenfbb39c81999-11-08 17:00:52 +0000190 } while (--argc > 0);
Eric Andersen3cf52d11999-10-12 22:26:06 +0000191end:
Eric Andersen50d63601999-11-09 01:47:36 +0000192#ifdef BB_FEATURE_USE_TERMIOS
Eric Andersen3cf52d11999-10-12 22:26:06 +0000193 gotsig(0);
194#endif
195 exit(TRUE);
Eric Andersencc8ed391999-10-05 16:24:54 +0000196}
Eric Andersen4bea32a1999-10-06 00:30:51 +0000197