diff options
Diffstat (limited to 'more.c')
-rw-r--r-- | more.c | 110 |
1 files changed, 110 insertions, 0 deletions
@@ -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; +} |