/* vi: set sw=4 ts=4: */
/*
 * Mini more implementation for busybox
 *
 *
 * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>.
 *
 * Latest version blended together by Erik Andersen <andersen@lineo.com>,
 * based on the original more implementation by Bruce, and code from the 
 * Debian boot-floppies team.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 */

#include "internal.h"
#include <stdio.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/ioctl.h>
#define BB_DECLARE_EXTERN
#define bb_need_help
#include "messages.c"

static const char more_usage[] = "more [FILE ...]\n"
#ifndef BB_FEATURE_TRIVIAL_HELP
	"\nMore is a filter for viewing FILE one screenful at a time.\n"
#endif
	;

/* ED: sparc termios is broken: revert back to old termio handling. */
#ifdef BB_FEATURE_USE_TERMIOS

#if #cpu(sparc)
#      include <termio.h>
#      define termios termio
#      define setTermSettings(fd,argp) ioctl(fd,TCSETAF,argp)
#      define getTermSettings(fd,argp) ioctl(fd,TCGETA,argp)
#else
#      include <termios.h>
#      define setTermSettings(fd,argp) tcsetattr(fd,TCSANOW,argp)
#      define getTermSettings(fd,argp) tcgetattr(fd, argp);
#endif

FILE *cin;

struct termios initial_settings, new_settings;

void gotsig(int sig)
{
	setTermSettings(fileno(cin), &initial_settings);
	fprintf(stdout, "\n");
	exit(TRUE);
}
#endif



#define TERMINAL_WIDTH	79		/* not 80 in case terminal has linefold bug */
#define TERMINAL_HEIGHT	24


#if defined BB_FEATURE_AUTOWIDTH
#ifdef BB_FEATURE_USE_TERMIOS
static int terminal_width = TERMINAL_WIDTH;
#endif
static int terminal_height = TERMINAL_HEIGHT;
#else
#define terminal_width	TERMINAL_WIDTH
#define terminal_height	TERMINAL_HEIGHT
#endif



extern int more_main(int argc, char **argv)
{
	int c, lines = 0, input = 0;
	int next_page = 0;
	struct stat st;
	FILE *file;

#if defined BB_FEATURE_AUTOWIDTH && defined BB_FEATURE_USE_TERMIOS
	struct winsize win = { 0, 0 };
#endif

	argc--;
	argv++;

	if (argc > 0
		&& (strcmp(*argv, dash_dash_help) == 0 || strcmp(*argv, "-h") == 0)) {
		usage(more_usage);
	}
	do {
		if (argc == 0) {
			file = stdin;
		} else
			file = fopen(*argv, "r");

		if (file == NULL) {
			perror(*argv);
			exit(FALSE);
		}
		fstat(fileno(file), &st);

#ifdef BB_FEATURE_USE_TERMIOS
		cin = fopen("/dev/tty", "r");
		if (!cin)
			cin = fopen("/dev/console", "r");
		getTermSettings(fileno(cin), &initial_settings);
		new_settings = initial_settings;
		new_settings.c_cc[VMIN] = 1;
		new_settings.c_cc[VTIME] = 0;
		new_settings.c_lflag &= ~ICANON;
		new_settings.c_lflag &= ~ECHO;
		setTermSettings(fileno(cin), &new_settings);

#ifdef BB_FEATURE_AUTOWIDTH
		ioctl(fileno(stdout), TIOCGWINSZ, &win);
		if (win.ws_row > 4)
			terminal_height = win.ws_row - 2;
		if (win.ws_col > 0)
			terminal_width = win.ws_col - 1;
#endif

		(void) signal(SIGINT, gotsig);
		(void) signal(SIGQUIT, gotsig);
		(void) signal(SIGTERM, gotsig);

#endif
		while ((c = getc(file)) != EOF) {
			if (next_page) {
				int len = 0;

				next_page = 0;
				lines = 0;
				len = fprintf(stdout, "--More-- ");
				if (file != stdin) {
					len += fprintf(stdout, "(%d%% of %ld bytes)",
								   (int) (100 *
										  ((double) ftell(file) /
										   (double) st.st_size)),
								   st.st_size);
				}
				len += fprintf(stdout, "%s",
#ifdef BB_FEATURE_USE_TERMIOS
							   ""
#else
							   "\n"
#endif
					);

				fflush(stdout);
#ifdef BB_FEATURE_USE_TERMIOS
				input = getc(cin);
#else
				input = getc(stdin);
#endif

#ifdef BB_FEATURE_USE_TERMIOS
				/* Erase the "More" message */
				while (--len >= 0)
					putc('\b', stdout);
				while (++len <= terminal_width)
					putc(' ', stdout);
				while (--len >= 0)
					putc('\b', stdout);
				fflush(stdout);
#endif

			}
			if (c == '\n') {
				switch (input) {
				case 'q':
					goto end;
				case '\n':
					/* increment by just one line if we are at 
					 * the end of this line*/
					next_page = 1;
					break;
				}
				if (++lines == terminal_height)
					next_page = 1;
			}
			putc(c, stdout);
		}
		fclose(file);
		fflush(stdout);

		argv++;
	} while (--argc > 0);
  end:
#ifdef BB_FEATURE_USE_TERMIOS
	gotsig(0);
#endif
	exit(TRUE);
}
