2 * Copyright (C) 1984-2012 Mark Nudelman
3 * Modified for use with illumos by Garrett D'Amore.
4 * Copyright 2014 Garrett D'Amore <garrett@damore.org>
6 * You may distribute under the terms of either the GNU General Public
7 * License or the Less License, as specified in the README file.
9 * For more information, see the README file.
13 * Entry point, initialization, miscellaneous routines.
16 #include <sys/types.h>
23 char *every_first_cmd
= NULL
;
26 IFILE curr_ifile
= NULL
;
27 IFILE old_ifile
= NULL
;
28 struct scrpos initial_scrpos
;
29 int any_display
= FALSE
;
30 off_t start_attnpos
= -1;
31 off_t end_attnpos
= -1;
34 static char *progname
;
41 int force_logfile
= FALSE
;
42 char *namelogfile
= NULL
;
47 extern char *tagoption
;
48 extern int jump_sline
;
49 extern int less_is_more
;
50 extern int missing_cap
;
52 extern int quit_if_one_screen
;
53 extern int quit_at_eof
;
55 extern int hilite_search
;
56 extern int use_lessopen
;
58 extern int top_scroll
;
66 main(int argc
, char *argv
[])
71 progname
= basename(argv
[0]);
76 * If the name of the executable program is "more",
77 * act like LESS_IS_MORE is set. We have to set this as early
78 * as possible for POSIX.
80 if (strcmp(progname
, "more") == 0)
83 s
= lgetenv("LESS_IS_MORE");
84 if (s
!= NULL
&& *s
!= '\0')
89 s
= lgetenv("LESSSECURE");
90 if (s
!= NULL
&& *s
!= '\0')
94 if (pledge("stdio rpath wpath tty", NULL
) == -1) {
99 if (pledge("stdio rpath wpath cpath fattr proc exec tty", NULL
) == -1) {
106 * Process command line arguments and LESS environment arguments.
107 * Command line arguments override environment arguments.
122 /* this is specified by XPG */
123 quit_at_eof
= OPT_ON
;
125 /* more users don't like the warning */
128 /* default prompt is medium */
131 /* do not hilight search terms */
132 hilite_search
= OPT_OFF
;
134 /* do not use LESSOPEN */
135 use_lessopen
= OPT_OFF
;
137 /* do not set init strings to terminal */
140 /* repaint from top of screen */
141 top_scroll
= OPT_OFF
;
144 s
= lgetenv(less_is_more
? "MORE" : "LESS");
146 scan_option(estrdup(s
));
148 #define isoptstring(s) (((s)[0] == '-' || (s)[0] == '+') && (s)[1] != '\0')
149 while (argc
> 0 && (isoptstring(*argv
) || isoptpending())) {
152 if (strcmp(s
, "--") == 0)
158 if (isoptpending()) {
160 * Last command line option was a flag requiring a
161 * following string, but there was no following string.
170 if (less_is_more
&& quit_at_eof
== OPT_ONPLUS
) {
174 if (less_is_more
&& pr_type
== OPT_ONPLUS
) {
179 editor
= lgetenv("VISUAL");
180 if (editor
== NULL
|| *editor
== '\0') {
181 editor
= lgetenv("EDITOR");
182 if (editor
== NULL
|| *editor
== '\0')
185 editproto
= lgetenv("LESSEDIT");
186 if (editproto
== NULL
|| *editproto
== '\0')
187 editproto
= "%E ?lm+%lm. %f";
190 * Call get_ifile with all the command line filenames
191 * to "register" them with the ifile system.
195 ifile
= get_ifile(helpfile(), ifile
);
198 filename
= shell_quote(*argv
);
199 if (filename
== NULL
)
202 (void) get_ifile(filename
, ifile
);
203 ifile
= prev_ifile(NULL
);
207 * Set up terminal, etc.
211 * Output is not a tty.
212 * Just copy the input file(s) to output.
215 if (edit_stdin() == 0)
217 } else if (edit_first() == 0) {
220 } while (edit_next(1) == 0);
225 if (missing_cap
&& !know_dumb
)
226 error("WARNING: terminal is not fully functional", NULL
);
231 if (pledge("stdio rpath tty", NULL
) == -1) {
240 * Select the first file to examine.
242 if (tagoption
!= NULL
|| strcmp(tags
, "-") == 0) {
244 * A -t option was given.
245 * Verify that no filenames were also given.
246 * Edit the file selected by the "tags" search,
247 * and search for the proper line in the file.
250 error("No filenames allowed with -t option", NULL
);
254 if (edit_tagfile()) /* Edit file which contains the tag */
257 * Search for the line which contains the tag.
258 * Set up initial_scrpos so we display that line.
260 initial_scrpos
.pos
= tagsearch();
261 if (initial_scrpos
.pos
== -1)
263 initial_scrpos
.ln
= jump_sline
;
264 } else if (nifile() == 0) {
265 if (edit_stdin()) /* Edit standard input */
268 if (edit_first()) /* Edit first valid file in cmd line */
280 * Like calloc(), but never returns an error (NULL).
283 ecalloc(int count
, unsigned int size
)
287 p
= calloc(count
, size
);
290 error("Cannot allocate memory", NULL
);
296 easprintf(const char *fmt
, ...)
303 rv
= vasprintf(&p
, fmt
, ap
);
306 if (p
== NULL
|| rv
< 0) {
307 error("Cannot allocate memory", NULL
);
314 estrdup(const char *str
)
320 error("Cannot allocate memory", NULL
);
327 * Skip leading spaces in a string.
332 while (*s
== ' ' || *s
== '\t')
338 * See how many characters of two strings are identical.
339 * If uppercase is true, the first string must begin with an uppercase
340 * character; the remainder of the first string may be either case.
343 sprefix(char *ps
, char *s
, int uppercase
)
349 for (; *s
!= '\0'; s
++, ps
++) {
352 if (len
== 0 && islower(c
))
372 static int save_status
;
375 * Put cursor at bottom left corner, clear the line,
376 * reset the terminal modes, and exit.
379 status
= save_status
;
381 save_status
= status
;
386 if (any_display
&& is_tty
)
397 return (less_is_more
? HELPDIR
"/more.help" : HELPDIR
"/less.help");