diff options
Diffstat (limited to 'more.c')
-rw-r--r-- | more.c | 110 |
1 files changed, 110 insertions, 0 deletions
@@ -0,0 +1,110 @@ | |||
1 | #include "internal.h" | ||
2 | #include <stdio.h> | ||
3 | #include <sys/types.h> | ||
4 | #include <sys/stat.h> | ||
5 | #include <sys/ioctl.h> | ||
6 | #include <fcntl.h> | ||
7 | |||
8 | #define BB_MORE_TERM | ||
9 | |||
10 | #ifdef BB_MORE_TERM | ||
11 | #include <termios.h> | ||
12 | #include <signal.h> | ||
13 | |||
14 | FILE *cin; | ||
15 | struct termios initial_settings, new_settings; | ||
16 | |||
17 | void gotsig(int sig) { | ||
18 | tcsetattr(fileno(cin), TCSANOW, &initial_settings); | ||
19 | exit(0); | ||
20 | } | ||
21 | #endif | ||
22 | |||
23 | const char more_usage[] = "more [file]\n" | ||
24 | "\n" | ||
25 | "\tDisplays a file, one page at a time.\n" | ||
26 | "\tIf there are no arguments, the standard input is displayed.\n"; | ||
27 | |||
28 | extern int | ||
29 | more_fn(const struct FileInfo * i) | ||
30 | { | ||
31 | FILE * f = stdin; | ||
32 | int c; | ||
33 | int lines = 0, tlines = 0; | ||
34 | int next_page = 0; | ||
35 | int rows = 24, cols = 79; | ||
36 | #ifdef BB_MORE_TERM | ||
37 | long sizeb = 0; | ||
38 | struct stat st; | ||
39 | struct winsize win; | ||
40 | #endif | ||
41 | |||
42 | if ( i ) { | ||
43 | if (! (f = fopen(i->source, "r") )) { | ||
44 | name_and_error(i->source); | ||
45 | return 1; | ||
46 | } | ||
47 | fstat(fileno(f), &st); | ||
48 | sizeb = st.st_size / 100; | ||
49 | } | ||
50 | |||
51 | #ifdef BB_MORE_TERM | ||
52 | cin = fopen("/dev/tty", "r"); | ||
53 | tcgetattr(fileno(cin),&initial_settings); | ||
54 | new_settings = initial_settings; | ||
55 | new_settings.c_lflag &= ~ICANON; | ||
56 | new_settings.c_lflag &= ~ECHO; | ||
57 | tcsetattr(fileno(cin), TCSANOW, &new_settings); | ||
58 | |||
59 | (void) signal(SIGINT, gotsig); | ||
60 | |||
61 | ioctl(STDOUT_FILENO, TIOCGWINSZ, &win); | ||
62 | if (win.ws_row > 4) rows = win.ws_row - 2; | ||
63 | if (win.ws_col > 0) cols = win.ws_col - 1; | ||
64 | |||
65 | |||
66 | #endif | ||
67 | |||
68 | while ( (c = getc(f)) != EOF ) { | ||
69 | if ( next_page ) { | ||
70 | char garbage; | ||
71 | int len; | ||
72 | tlines += lines; | ||
73 | lines = 0; | ||
74 | next_page = 0; //Percentage is based on bytes, not lines. | ||
75 | if ( i && i->source ) //It is not very acurate, but still useful. | ||
76 | len = printf("%s - %%%2ld - line: %d", i->source, (ftell(f) - sizeb - sizeb) / sizeb, tlines); | ||
77 | else | ||
78 | len = printf("line: %d", tlines); | ||
79 | |||
80 | fflush(stdout); | ||
81 | #ifndef BB_MORE_TERM | ||
82 | read(2, &garbage, 1); | ||
83 | #else | ||
84 | do { | ||
85 | fread(&garbage, 1, 1, cin); | ||
86 | } while ((garbage != ' ') && (garbage != '\n')); | ||
87 | |||
88 | if (garbage == '\n') { | ||
89 | lines = rows; | ||
90 | tlines -= rows; | ||
91 | } | ||
92 | garbage = 0; | ||
93 | //clear line, since tabs don't overwrite. | ||
94 | while(len-- > 0) putchar('\b'); | ||
95 | while(len++ < cols) putchar(' '); | ||
96 | while(len-- > 0) putchar('\b'); | ||
97 | fflush(stdout); | ||
98 | #endif | ||
99 | } | ||
100 | putchar(c); | ||
101 | if ( c == '\n' && ++lines == (rows + 1) ) | ||
102 | next_page = 1; | ||
103 | } | ||
104 | if ( f != stdin ) | ||
105 | fclose(f); | ||
106 | #ifdef BB_MORE_TERM | ||
107 | gotsig(0); | ||
108 | #endif | ||
109 | return 0; | ||
110 | } | ||