aboutsummaryrefslogtreecommitdiff
path: root/util-linux/more.c
diff options
context:
space:
mode:
Diffstat (limited to 'util-linux/more.c')
-rw-r--r--util-linux/more.c110
1 files changed, 110 insertions, 0 deletions
diff --git a/util-linux/more.c b/util-linux/more.c
new file mode 100644
index 000000000..65409999b
--- /dev/null
+++ b/util-linux/more.c
@@ -0,0 +1,110 @@
+#include "internal.h"
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+
+#define BB_MORE_TERM
+
+#ifdef BB_MORE_TERM
+ #include <termios.h>
+ #include <signal.h>
+
+ FILE *cin;
+ struct termios initial_settings, new_settings;
+
+ void gotsig(int sig) {
+ tcsetattr(fileno(cin), TCSANOW, &initial_settings);
+ exit(0);
+ }
+#endif
+
+const char more_usage[] = "more [file]\n"
+"\n"
+"\tDisplays a file, one page at a time.\n"
+"\tIf there are no arguments, the standard input is displayed.\n";
+
+extern int
+more_fn(const struct FileInfo * i)
+{
+ FILE * f = stdin;
+ int c;
+ int lines = 0, tlines = 0;
+ int next_page = 0;
+ int rows = 24, cols = 79;
+#ifdef BB_MORE_TERM
+ long sizeb = 0;
+ struct stat st;
+ struct winsize win;
+#endif
+
+ if ( i ) {
+ if (! (f = fopen(i->source, "r") )) {
+ name_and_error(i->source);
+ return 1;
+ }
+ fstat(fileno(f), &st);
+ sizeb = st.st_size / 100;
+ }
+
+#ifdef BB_MORE_TERM
+ cin = fopen("/dev/tty", "r");
+ tcgetattr(fileno(cin),&initial_settings);
+ new_settings = initial_settings;
+ new_settings.c_lflag &= ~ICANON;
+ new_settings.c_lflag &= ~ECHO;
+ tcsetattr(fileno(cin), TCSANOW, &new_settings);
+
+ (void) signal(SIGINT, gotsig);
+
+ ioctl(STDOUT_FILENO, TIOCGWINSZ, &win);
+ if (win.ws_row > 4) rows = win.ws_row - 2;
+ if (win.ws_col > 0) cols = win.ws_col - 1;
+
+
+#endif
+
+ while ( (c = getc(f)) != EOF ) {
+ if ( next_page ) {
+ char garbage;
+ int len;
+ tlines += lines;
+ lines = 0;
+ next_page = 0; //Percentage is based on bytes, not lines.
+ if ( i && i->source ) //It is not very acurate, but still useful.
+ len = printf("%s - %%%2ld - line: %d", i->source, (ftell(f) - sizeb - sizeb) / sizeb, tlines);
+ else
+ len = printf("line: %d", tlines);
+
+ fflush(stdout);
+#ifndef BB_MORE_TERM
+ read(2, &garbage, 1);
+#else
+ do {
+ fread(&garbage, 1, 1, cin);
+ } while ((garbage != ' ') && (garbage != '\n'));
+
+ if (garbage == '\n') {
+ lines = rows;
+ tlines -= rows;
+ }
+ garbage = 0;
+ //clear line, since tabs don't overwrite.
+ while(len-- > 0) putchar('\b');
+ while(len++ < cols) putchar(' ');
+ while(len-- > 0) putchar('\b');
+ fflush(stdout);
+#endif
+ }
+ putchar(c);
+ if ( c == '\n' && ++lines == (rows + 1) )
+ next_page = 1;
+ }
+ if ( f != stdin )
+ fclose(f);
+#ifdef BB_MORE_TERM
+ gotsig(0);
+#endif
+ return 0;
+}