Contents of /trunk/mkinitrd-magellan/busybox/util-linux/more.c
Parent Directory
|
Revision Log
Revision 532 -
(show annotations)
(download)
Sat Sep 1 22:45:15 2007 UTC (16 years, 9 months ago) by niro
File MIME type: text/plain
File size: 4333 byte(s)
Sat Sep 1 22:45:15 2007 UTC (16 years, 9 months ago) by niro
File MIME type: text/plain
File size: 4333 byte(s)
-import if magellan mkinitrd; it is a fork of redhats mkinitrd-5.0.8 with all magellan patches and features; deprecates magellan-src/mkinitrd
1 | /* vi: set sw=4 ts=4: */ |
2 | /* |
3 | * Mini more implementation for busybox |
4 | * |
5 | * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>. |
6 | * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> |
7 | * |
8 | * Latest version blended together by Erik Andersen <andersen@codepoet.org>, |
9 | * based on the original more implementation by Bruce, and code from the |
10 | * Debian boot-floppies team. |
11 | * |
12 | * Termios corrects by Vladimir Oleynik <dzo@simtreas.ru> |
13 | * |
14 | * Licensed under GPLv2 or later, see file License in this tarball for details. |
15 | */ |
16 | |
17 | #include "busybox.h" |
18 | |
19 | |
20 | #if ENABLE_FEATURE_USE_TERMIOS |
21 | static int cin_fileno; |
22 | #include <termios.h> |
23 | #define setTermSettings(fd, argp) tcsetattr(fd, TCSANOW, argp) |
24 | #define getTermSettings(fd, argp) tcgetattr(fd, argp); |
25 | |
26 | static struct termios initial_settings, new_settings; |
27 | |
28 | static void set_tty_to_initial_mode(void) |
29 | { |
30 | setTermSettings(cin_fileno, &initial_settings); |
31 | } |
32 | |
33 | static void gotsig(int sig) |
34 | { |
35 | putchar('\n'); |
36 | exit(EXIT_FAILURE); |
37 | } |
38 | #endif /* FEATURE_USE_TERMIOS */ |
39 | |
40 | |
41 | int more_main(int argc, char **argv) |
42 | { |
43 | int c, lines, input = 0; |
44 | int please_display_more_prompt = 0; |
45 | struct stat st; |
46 | FILE *file; |
47 | FILE *cin; |
48 | int len, page_height; |
49 | int terminal_width; |
50 | int terminal_height; |
51 | |
52 | argc--; |
53 | argv++; |
54 | |
55 | cin = stdin; |
56 | /* use input from terminal unless we do "more >outfile" */ |
57 | if (isatty(STDOUT_FILENO)) { |
58 | cin = fopen(CURRENT_TTY, "r"); |
59 | if (!cin) |
60 | cin = xfopen(CONSOLE_DEV, "r"); |
61 | please_display_more_prompt = 2; |
62 | #if ENABLE_FEATURE_USE_TERMIOS |
63 | cin_fileno = fileno(cin); |
64 | getTermSettings(cin_fileno, &initial_settings); |
65 | new_settings = initial_settings; |
66 | new_settings.c_lflag &= ~ICANON; |
67 | new_settings.c_lflag &= ~ECHO; |
68 | new_settings.c_cc[VMIN] = 1; |
69 | new_settings.c_cc[VTIME] = 0; |
70 | setTermSettings(cin_fileno, &new_settings); |
71 | atexit(set_tty_to_initial_mode); |
72 | signal(SIGINT, gotsig); |
73 | signal(SIGQUIT, gotsig); |
74 | signal(SIGTERM, gotsig); |
75 | #endif |
76 | } |
77 | |
78 | do { |
79 | file = stdin; |
80 | if (argc != 0) { |
81 | file = fopen_or_warn(*argv, "r"); |
82 | if (!file) |
83 | goto loop; |
84 | } |
85 | |
86 | st.st_size = 0; |
87 | fstat(fileno(file), &st); |
88 | |
89 | please_display_more_prompt &= ~1; |
90 | |
91 | get_terminal_width_height(fileno(cin), &terminal_width, &terminal_height); |
92 | if (terminal_height > 4) |
93 | terminal_height -= 2; |
94 | if (terminal_width > 0) |
95 | terminal_width -= 1; |
96 | |
97 | len = 0; |
98 | lines = 0; |
99 | page_height = terminal_height; |
100 | while ((c = getc(file)) != EOF) { |
101 | |
102 | if ((please_display_more_prompt & 3) == 3) { |
103 | len = printf("--More-- "); |
104 | if (file != stdin && st.st_size > 0) { |
105 | len += printf("(%d%% of %"OFF_FMT"d bytes)", |
106 | (int) (ftello(file)*100 / st.st_size), |
107 | st.st_size); |
108 | } |
109 | fflush(stdout); |
110 | |
111 | /* |
112 | * We've just displayed the "--More--" prompt, so now we need |
113 | * to get input from the user. |
114 | */ |
115 | input = getc(cin); |
116 | #if !ENABLE_FEATURE_USE_TERMIOS |
117 | printf("\033[A"); /* up cursor */ |
118 | #endif |
119 | /* Erase the "More" message */ |
120 | printf("\r%*s\r", len, ""); |
121 | len = 0; |
122 | lines = 0; |
123 | page_height = terminal_height; |
124 | please_display_more_prompt &= ~1; |
125 | |
126 | if (input == 'q') |
127 | goto end; |
128 | } |
129 | |
130 | /* |
131 | * There are two input streams to worry about here: |
132 | * |
133 | * c : the character we are reading from the file being "mored" |
134 | * input : a character received from the keyboard |
135 | * |
136 | * If we hit a newline in the _file_ stream, we want to test and |
137 | * see if any characters have been hit in the _input_ stream. This |
138 | * allows the user to quit while in the middle of a file. |
139 | */ |
140 | if (c == '\n') { |
141 | /* increment by just one line if we are at |
142 | * the end of this line */ |
143 | if (input == '\n') |
144 | please_display_more_prompt |= 1; |
145 | /* Adjust the terminal height for any overlap, so that |
146 | * no lines get lost off the top. */ |
147 | if (len >= terminal_width) { |
148 | int quot, rem; |
149 | quot = len / terminal_width; |
150 | rem = len - (quot * terminal_width); |
151 | if (quot) { |
152 | if (rem) |
153 | page_height -= quot; |
154 | else |
155 | page_height -= (quot - 1); |
156 | } |
157 | } |
158 | if (++lines >= page_height) { |
159 | please_display_more_prompt |= 1; |
160 | } |
161 | len = 0; |
162 | } |
163 | /* |
164 | * If we just read a newline from the file being 'mored' and any |
165 | * key other than a return is hit, scroll by one page |
166 | */ |
167 | putc(c, stdout); |
168 | len++; |
169 | } |
170 | fclose(file); |
171 | fflush(stdout); |
172 | loop: |
173 | argv++; |
174 | } while (--argc > 0); |
175 | end: |
176 | return 0; |
177 | } |