121
121
#define RUBOUT '\177'
122
122
#define ESC '\033'
123
123
#define QUIT '\034'
124
#define SCROLL_LEN 11
125
#define LINES_PER_PAGE 24
126
#define NUM_COLUMNS 80
127
#define TERMINAL_BUF 4096
129
#define SHELL_LINE 1000
130
#define COMMAND_BUF 200
125
132
struct termios otty, savetty0;
126
133
long file_pos, file_size;
127
134
int fnum, no_intty, no_tty, slow_tty;
128
135
int dum_opt, dlines;
129
136
void onquit(int), onsusp(int), chgwinsz(int), end_it(int);
130
int nscroll = 11; /* Number of lines scrolled by 'd' */
131
int fold_opt = 1; /* Fold long lines */
132
int stop_opt = 1; /* Stop after form feeds */
133
int ssp_opt = 0; /* Suppress white space */
134
int ul_opt = 1; /* Underline as best we can */
137
int nscroll = SCROLL_LEN; /* Number of lines scrolled by 'd' */
138
int fold_opt = 1; /* Fold long lines */
139
int stop_opt = 1; /* Stop after form feeds */
140
int ssp_opt = 0; /* Suppress white space */
141
int ul_opt = 1; /* Underline as best we can */
136
int Currline; /* Line we are currently at */
143
int Currline; /* Line we are currently at */
140
147
int docrterase = 0;
141
148
int docrtkill = 0;
142
int bad_so; /* True if overwriting does not turn off standout */
149
int bad_so; /* True if overwriting does not turn
143
151
int inwait, Pause, errors;
144
int within; /* true if we are within a file,
145
false if we are between files */
152
int within; /* true if we are within a file,
153
false if we are between files */
146
154
int hard, dumb, noscroll, hardtabs, clreol, eatnl;
147
int catch_susp; /* We should catch the SIGTSTP signal */
148
char **fnames; /* The list of file names */
149
int nfiles; /* Number of files left to process */
150
char *shell; /* The name of the shell to use */
151
int shellp; /* A previous shell command exists */
155
int catch_susp; /* We should catch the SIGTSTP signal */
156
char **fnames; /* The list of file names */
157
int nfiles; /* Number of files left to process */
158
char *shell; /* The name of the shell to use */
159
int shellp; /* A previous shell command exists */
152
160
sigjmp_buf restore;
153
char *Line; /* Line buffer */
154
size_t LineLen; /* size of Line buffer */
155
int Lpp = 24; /* lines per page */
156
char *Clear; /* clear screen */
157
char *eraseln; /* erase line */
158
char *Senter, *Sexit;/* enter and exit standout mode */
161
char *Line; /* Line buffer */
162
size_t LineLen; /* size of Line buffer */
163
int Lpp = LINES_PER_PAGE; /* lines per page */
164
char *Clear; /* clear screen */
165
char *eraseln; /* erase line */
166
char *Senter, *Sexit; /* enter and exit standout mode */
159
167
char *ULenter, *ULexit; /* enter and exit underline mode */
160
char *chUL; /* underline character */
161
char *chBS; /* backspace character */
162
char *Home; /* go to home */
163
char *cursorm; /* cursor movement */
164
char cursorhome[40]; /* contains cursor movement to home */
165
char *EodClr; /* clear rest of screen */
166
int Mcol = 80; /* number of columns */
167
int Wrap = 1; /* set if automargins */
168
int soglitch; /* terminal has standout mode glitch */
169
int ulglitch; /* terminal has underline mode glitch */
170
int pstate = 0; /* current UL state */
168
char *chUL; /* underline character */
169
char *chBS; /* backspace character */
170
char *Home; /* go to home */
171
char *cursorm; /* cursor movement */
172
char cursorhome[40]; /* contains cursor movement to home */
173
char *EodClr; /* clear rest of screen */
174
int Mcol = NUM_COLUMNS; /* number of columns */
175
int Wrap = 1; /* set if automargins */
176
int soglitch; /* terminal has standout mode glitch */
177
int ulglitch; /* terminal has underline mode glitch */
178
int pstate = 0; /* current UL state */
171
179
static int magic(FILE *, char *);
173
181
long chrctr, line;
178
186
# include <ncurses.h>
179
187
#elif defined(HAVE_NCURSES_NCURSES_H)
180
188
# include <ncurses/ncurses.h>
189
#endif /* HAVE_NCURSES_H */
183
191
#if defined(HAVE_NCURSES_H) || defined(HAVE_NCURSES_NCURSES_H)
184
192
# include <term.h> /* include after <curses.h> */
187
my_putstring(char *s) {
188
tputs (s, 1, putchar); /* putp(s); */
194
#define TERM_AUTO_RIGHT_MARGIN "am"
195
#define TERM_CEOL "xhp"
196
#define TERM_CLEAR "clear"
197
#define TERM_CLEAR_TO_LINE_END "el"
198
#define TERM_CLEAR_TO_SCREEN_END "ed"
199
#define TERM_COLS "cols"
200
#define TERM_CURSOR_ADDRESS "cup"
201
#define TERM_EAT_NEW_LINE "xenl"
202
#define TERM_ENTER_UNDERLINE "smul"
203
#define TERM_EXIT_STANDARD_MODE "rmso"
204
#define TERM_EXIT_UNDERLINE "rmul"
205
#define TERM_HARD_COPY "hc"
206
#define TERM_HOME "home"
207
#define TERM_LINE_DOWN "cud1"
208
#define TERM_LINES "lines"
209
#define TERM_OVER_STRIKE "os"
210
#define TERM_PAD_CHAR "pad"
211
#define TERM_STANDARD_MODE "smso"
212
#define TERM_STD_MODE_GLITCH "xmc"
213
#define TERM_UNDERLINE_CHAR "uc"
214
#define TERM_UNDERLINE "ul"
216
static void my_putstring(char *s) {
217
tputs (s, fileno(stdout), putchar); /* putp(s); */
192
my_setupterm(char *term, int fildes, int *errret) {
220
static void my_setupterm(char *term, int fildes, int *errret) {
193
221
setupterm(term, fildes, errret);
197
my_tgetnum(char *s, char *ss) {
202
my_tgetflag(char *s, char *ss) {
203
return tigetflag(ss);
207
my_tgetstr(char *s, char *ss) {
212
my_tgoto(char *cap, int col, int row) {
224
static int my_tgetnum(char *s) {
228
static int my_tgetflag(char *s) {
232
static char *my_tgetstr(char *s) {
236
static char *my_tgoto(char *cap, int col, int row) {
213
237
return tparm(cap, col, row);
218
242
#include <termcap.h>
220
char termbuffer[4096];
244
#define TERM_AUTO_RIGHT_MARGIN "am"
245
#define TERM_CEOL "xs"
246
#define TERM_CLEAR "cl"
247
#define TERM_CLEAR_TO_LINE_END "ce"
248
#define TERM_CLEAR_TO_SCREEN_END "cd"
249
#define TERM_COLS "co"
250
#define TERM_CURSOR_ADDRESS "cm"
251
#define TERM_EAT_NEW_LINE "xn"
252
#define TERM_ENTER_UNDERLINE "us"
253
#define TERM_EXIT_STANDARD_MODE "se"
254
#define TERM_EXIT_UNDERLINE "ue"
255
#define TERM_HARD_COPY "hc"
256
#define TERM_HOME "ho"
257
#define TERM_LINE_DOWN "le"
258
#define TERM_LINES "li"
259
#define TERM_OVER_STRIKE "os"
260
#define TERM_PAD_CHAR "pc"
261
#define TERM_STANDARD_MODE "so"
262
#define TERM_STD_MODE_GLITCH "sg"
263
#define TERM_UNDERLINE_CHAR "uc"
264
#define TERM_UNDERLINE "ul"
266
char termbuffer[TERMINAL_BUF];
267
char tcbuffer[TERMINAL_BUF];
222
268
char *strbuf = termbuffer;
225
my_putstring(char *s) {
226
tputs (s, 1, putchar);
270
static void my_putstring(char *s) {
271
tputs (s, fileno(stdout), putchar);
230
my_setupterm(char *term, int fildes, int *errret) {
274
static void my_setupterm(char *term, int fildes, int *errret) {
231
275
*errret = tgetent(tcbuffer, term);
235
my_tgetnum(char *s, char *ss) {
278
static int my_tgetnum(char *s) {
236
279
return tgetnum(s);
240
my_tgetflag(char *s, char *ss) {
282
static int my_tgetflag(char *s) {
241
283
return tgetflag(s);
245
my_tgetstr(char *s, char *ss) {
286
static char *my_tgetstr(char *s) {
246
287
return tgetstr(s, &strbuf);
250
my_tgoto(char *cap, int col, int row) {
290
static char *my_tgoto(char *cap, int col, int row) {
251
291
return tgoto(cap, col, row);
254
294
#endif /* HAVE_LIBTERMCAP */
264
char *p = strrchr(s, '/');
266
_("usage: %s [-dflpcsu] [+linenum | +/pattern] name1 name2 ...\n"),
296
static void __attribute__ ((__noreturn__)) usage(FILE *out)
299
_("Usage: %s [options] file...\n\n"),
300
program_invocation_short_name);
303
" -d display help instead of ring bell\n"
304
" -f count logical, rather than screen lines\n"
305
" -l suppress pause after form feed\n"
306
" -p suppress scroll, clean screen and disblay text\n"
307
" -c suppress scroll, display text and clean line ends\n"
308
" -u suppress underlining\n"
309
" -s squeeze multiple blank lines into one\n"
310
" -NUM specify the number of lines per screenful\n"
311
" +NUM display file beginning from line number NUM\n"
312
" +/STRING display file beginning from search string match\n"
313
" -V output version information and exit\n"));
314
exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
270
317
int main(int argc, char **argv) {
280
327
int initline = 0;
328
char initbuf[INIT_BUF];
283
330
setlocale(LC_ALL, "");
284
331
bindtextdomain(PACKAGE, LOCALEDIR);
285
332
textdomain(PACKAGE);
287
/* avoid gcc complaints about register variables that
288
may be clobbered by a longjmp, by forcing our variables here
289
to be non-register */
290
Fdummy(&f); idummy(&left); idummy(&prnames);
291
idummy(&initopt); idummy(&srchopt); idummy(&initline);
295
336
setlocale(LC_ALL, "");
297
if (prepare_line_buffer()) {
298
fprintf(stderr, _("failed to initialize line buffer\n"));
339
/* Auto set no scroll on when binary is called page */
340
if (!(strcmp(program_invocation_short_name, "page")))
343
prepare_line_buffer();
301
345
nscroll = Lpp/2 - 1;
302
346
if (nscroll <= 0)
304
if((s = getenv("MORE")) != NULL) argscan(s,argv[0]);
349
if ((s = getenv("MORE")) != NULL)
305
352
while (--nfiles > 0) {
306
353
if ((ch = (*++fnames)[0]) == '-') {
307
argscan(*fnames+1,argv[0]);
309
356
else if (ch == '+') {
311
358
if (*++s == '/') {
313
for (++s, p = initbuf; p < initbuf + 79 && *s != '\0';)
360
for (++s, p = initbuf; p < initbuf + (INIT_BUF - 1) && *s != '\0';)
1779
1800
#ifdef TIOCGWINSZ
1780
1801
if (ioctl(fileno(stdout), TIOCGWINSZ, &win) < 0) {
1782
Lpp = my_tgetnum("li","lines");
1783
Mcol = my_tgetnum("co","cols");
1802
#endif /* TIOCGWINSZ */
1803
Lpp = my_tgetnum(TERM_LINES);
1804
Mcol = my_tgetnum(TERM_COLS);
1784
1805
#ifdef TIOCGWINSZ
1786
1807
if ((Lpp = win.ws_row) == 0)
1787
Lpp = my_tgetnum("li","lines");
1808
Lpp = my_tgetnum(TERM_LINES);
1788
1809
if ((Mcol = win.ws_col) == 0)
1789
Mcol = my_tgetnum("co","cols");
1810
Mcol = my_tgetnum(TERM_COLS);
1792
if ((Lpp <= 0) || my_tgetflag("hc","hc")) {
1812
#endif /* TIOCGWINSZ */
1813
if ((Lpp <= 0) || my_tgetflag(TERM_HARD_COPY)) {
1793
1814
hard++; /* Hard copy terminal */
1815
Lpp = LINES_PER_PAGE;
1797
if (my_tgetflag("xn","xenl"))
1818
if (my_tgetflag(TERM_EAT_NEW_LINE))
1798
1819
eatnl++; /* Eat newline at last column + 1; dec, concept */
1802
if (tailequ (fnames[0], "page"))
1804
Wrap = my_tgetflag("am","am");
1805
bad_so = my_tgetflag ("xs","xhp");
1806
eraseln = my_tgetstr("ce","el");
1807
Clear = my_tgetstr("cl","clear");
1808
Senter = my_tgetstr("so","smso");
1809
Sexit = my_tgetstr("se","rmso");
1810
if ((soglitch = my_tgetnum("sg","xmc")) < 0)
1823
Wrap = my_tgetflag(TERM_AUTO_RIGHT_MARGIN);
1824
bad_so = my_tgetflag (TERM_CEOL);
1825
eraseln = my_tgetstr(TERM_CLEAR_TO_LINE_END);
1826
Clear = my_tgetstr(TERM_CLEAR);
1827
Senter = my_tgetstr(TERM_STANDARD_MODE);
1828
Sexit = my_tgetstr(TERM_EXIT_STANDARD_MODE);
1829
if ((soglitch = my_tgetnum(TERM_STD_MODE_GLITCH)) < 0)
1818
1837
* isn't available, settle for standout sequence.
1821
if (my_tgetflag("ul","ul") || my_tgetflag("os","os"))
1840
if (my_tgetflag(TERM_UNDERLINE) || my_tgetflag(TERM_OVER_STRIKE))
1823
if ((chUL = my_tgetstr("uc","uc")) == NULL )
1842
if ((chUL = my_tgetstr(TERM_UNDERLINE_CHAR)) == NULL )
1825
if (((ULenter = my_tgetstr("us","smul")) == NULL ||
1826
(ULexit = my_tgetstr("ue","rmul")) == NULL) && !*chUL) {
1844
if (((ULenter = my_tgetstr(TERM_ENTER_UNDERLINE)) == NULL ||
1845
(ULexit = my_tgetstr(TERM_EXIT_UNDERLINE)) == NULL) && !*chUL) {
1827
1846
if ((ULenter = Senter) == NULL || (ULexit = Sexit) == NULL) {
1836
if ((padstr = my_tgetstr("pc","pad")) != NULL)
1855
if ((padstr = my_tgetstr(TERM_PAD_CHAR)) != NULL)
1838
Home = my_tgetstr("ho","home");
1857
Home = my_tgetstr(TERM_HOME);
1839
1858
if (Home == 0 || *Home == '\0') {
1840
if ((cursorm = my_tgetstr("cm","cup")) != NULL) {
1859
if ((cursorm = my_tgetstr(TERM_CURSOR_ADDRESS)) != NULL) {
1841
1860
const char *t = (const char *)my_tgoto(cursorm, 0, 0);
1842
1861
xstrncpy(cursorhome, t, sizeof(cursorhome));
1843
1862
Home = cursorhome;
1846
EodClr = my_tgetstr("cd","ed");
1847
if ((chBS = my_tgetstr("le","cub1")) == NULL)
1865
EodClr = my_tgetstr(TERM_CLEAR_TO_SCREEN_END);
1866
if ((chBS = my_tgetstr(TERM_LINE_DOWN)) == NULL)