File: [local] / src / usr.bin / less / main.c (download)
Revision 1.38, Thu Sep 23 18:46:25 2021 UTC (2 years, 8 months ago) by tobias
Branch: MAIN
CVS Tags: OPENBSD_7_2_BASE, OPENBSD_7_2, OPENBSD_7_1_BASE, OPENBSD_7_1 Changes since 1.37: +1 -1 lines
Remove wpath from secure mode pledge.
Upstream removed history file support for secure mode. The history file
feature is off by default already, disallowing it altogether in secure
mode allows us to drop wpath.
Added a note about it to manual page.
ok benno, deraadt
|
/*
* Copyright (C) 1984-2012 Mark Nudelman
* Modified for use with illumos by Garrett D'Amore.
* Copyright 2014 Garrett D'Amore <garrett@damore.org>
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information, see the README file.
*/
/*
* Entry point, initialization, miscellaneous routines.
*/
#include <sys/types.h>
#include <libgen.h>
#include <stdarg.h>
#include "less.h"
char *every_first_cmd = NULL;
int new_file;
int is_tty;
IFILE curr_ifile = NULL;
IFILE old_ifile = NULL;
struct scrpos initial_scrpos;
int any_display = FALSE;
off_t start_attnpos = -1;
off_t end_attnpos = -1;
int wscroll;
static char *progname;
int quitting;
int secure;
int dohelp;
int logfile = -1;
int force_logfile = FALSE;
char *namelogfile = NULL;
char *editor;
char *editproto;
extern char *tags;
extern char *tagoption;
extern int jump_sline;
extern int less_is_more;
extern int missing_cap;
extern int know_dumb;
extern int quit_if_one_screen;
extern int quit_at_eof;
extern int pr_type;
extern int hilite_search;
extern int use_lessopen;
extern int no_init;
extern int top_scroll;
extern int errmsgs;
/*
* Entry point.
*/
int
main(int argc, char *argv[])
{
IFILE ifile;
char *s;
progname = basename(argv[0]);
argv++;
argc--;
/*
* If the name of the executable program is "more",
* act like LESS_IS_MORE is set. We have to set this as early
* as possible for POSIX.
*/
if (strcmp(progname, "more") == 0)
less_is_more = 1;
else {
s = lgetenv("LESS_IS_MORE");
if (s != NULL && *s != '\0')
less_is_more = 1;
}
secure = 0;
s = lgetenv("LESSSECURE");
if (s != NULL && *s != '\0')
secure = 1;
if (secure) {
if (pledge("stdio rpath tty", NULL) == -1) {
perror("pledge");
exit(1);
}
} else {
if (pledge("stdio rpath wpath cpath fattr proc exec tty", NULL) == -1) {
perror("pledge");
exit(1);
}
}
/*
* Process command line arguments and LESS environment arguments.
* Command line arguments override environment arguments.
*/
is_tty = isatty(1);
get_term();
init_cmds();
init_charset();
init_line();
init_cmdhist();
init_option();
init_search();
init_prompt();
if (less_is_more) {
/* this is specified by XPG */
quit_at_eof = OPT_ON;
/* more users don't like the warning */
know_dumb = OPT_ON;
/* default prompt is medium */
pr_type = OPT_ON;
/* do not hilight search terms */
hilite_search = OPT_OFF;
/* do not use LESSOPEN */
use_lessopen = OPT_OFF;
/* do not set init strings to terminal */
no_init = OPT_ON;
/* repaint from top of screen */
top_scroll = OPT_OFF;
}
s = lgetenv(less_is_more ? "MORE" : "LESS");
if (s != NULL)
scan_option(estrdup(s), 1);
#define isoptstring(s) (((s)[0] == '-' || (s)[0] == '+') && (s)[1] != '\0')
while (argc > 0 && (isoptstring(*argv) || isoptpending())) {
s = *argv++;
argc--;
if (strcmp(s, "--") == 0)
break;
scan_option(s, 0);
}
#undef isoptstring
if (isoptpending()) {
/*
* Last command line option was a flag requiring a
* following string, but there was no following string.
*/
nopendopt();
quit(QUIT_OK);
}
if (errmsgs) {
quit(QUIT_ERROR);
}
if (less_is_more && quit_at_eof == OPT_ONPLUS) {
extern int no_init;
no_init = OPT_ON;
}
if (less_is_more && pr_type == OPT_ONPLUS) {
extern int quiet;
quiet = VERY_QUIET;
}
editor = lgetenv("VISUAL");
if (editor == NULL || *editor == '\0') {
editor = lgetenv("EDITOR");
if (editor == NULL || *editor == '\0')
editor = EDIT_PGM;
}
editproto = lgetenv("LESSEDIT");
if (editproto == NULL || *editproto == '\0')
editproto = "%E ?lm+%lm. %f";
/*
* Call get_ifile with all the command line filenames
* to "register" them with the ifile system.
*/
ifile = NULL;
if (dohelp)
ifile = get_ifile(helpfile(), ifile);
while (argc-- > 0) {
char *filename;
filename = shell_quote(*argv);
if (filename == NULL)
filename = *argv;
argv++;
(void) get_ifile(filename, ifile);
ifile = prev_ifile(NULL);
free(filename);
}
/*
* Set up terminal, etc.
*/
if (!is_tty) {
/*
* Output is not a tty.
* Just copy the input file(s) to output.
*/
if (nifile() == 0) {
if (edit_stdin() == 0)
cat_file();
} else if (edit_first() == 0) {
do {
cat_file();
} while (edit_next(1) == 0);
}
quit(QUIT_OK);
}
if (missing_cap && !know_dumb)
error("WARNING: terminal is not fully functional", NULL);
init_mark();
open_getchr();
if (secure)
if (pledge("stdio rpath tty", NULL) == -1) {
perror("pledge");
exit(1);
}
raw_mode(1);
init_signals(1);
/*
* Select the first file to examine.
*/
if (tagoption != NULL || strcmp(tags, "-") == 0) {
/*
* A -t option was given.
* Verify that no filenames were also given.
* Edit the file selected by the "tags" search,
* and search for the proper line in the file.
*/
if (nifile() > 0) {
error("No filenames allowed with -t option", NULL);
quit(QUIT_ERROR);
}
findtag(tagoption);
if (edit_tagfile()) /* Edit file which contains the tag */
quit(QUIT_ERROR);
/*
* Search for the line which contains the tag.
* Set up initial_scrpos so we display that line.
*/
initial_scrpos.pos = tagsearch();
if (initial_scrpos.pos == -1)
quit(QUIT_ERROR);
initial_scrpos.ln = jump_sline;
} else if (nifile() == 0) {
if (edit_stdin()) /* Edit standard input */
quit(QUIT_ERROR);
} else {
if (edit_first()) /* Edit first valid file in cmd line */
quit(QUIT_ERROR);
}
init();
commands();
quit(QUIT_OK);
return (0);
}
/*
* Allocate memory.
* Like calloc(), but never returns an error (NULL).
*/
void *
ecalloc(int count, unsigned int size)
{
void *p;
p = calloc(count, size);
if (p != NULL)
return (p);
error("Cannot allocate memory", NULL);
quit(QUIT_ERROR);
return (NULL);
}
char *
easprintf(const char *fmt, ...)
{
char *p = NULL;
int rv;
va_list ap;
va_start(ap, fmt);
rv = vasprintf(&p, fmt, ap);
va_end(ap);
if (rv == -1) {
error("Cannot allocate memory", NULL);
quit(QUIT_ERROR);
}
return (p);
}
char *
estrdup(const char *str)
{
char *n;
n = strdup(str);
if (n == NULL) {
error("Cannot allocate memory", NULL);
quit(QUIT_ERROR);
}
return (n);
}
/*
* Skip leading spaces in a string.
*/
char *
skipsp(char *s)
{
while (*s == ' ' || *s == '\t')
s++;
return (s);
}
/*
* See how many characters of two strings are identical.
* If uppercase is true, the first string must begin with an uppercase
* character; the remainder of the first string may be either case.
*/
int
sprefix(char *ps, char *s, int uppercase)
{
int c;
int sc;
int len = 0;
for (; *s != '\0'; s++, ps++) {
c = *ps;
if (uppercase) {
if (len == 0 && islower(c))
return (-1);
c = tolower(c);
}
sc = *s;
if (len > 0)
sc = tolower(sc);
if (c != sc)
break;
len++;
}
return (len);
}
/*
* Exit the program.
*/
void
quit(int status)
{
static int save_status;
/*
* Put cursor at bottom left corner, clear the line,
* reset the terminal modes, and exit.
*/
if (status < 0)
status = save_status;
else
save_status = status;
quitting = 1;
edit(NULL);
if (!secure)
save_cmdhist();
if (any_display && is_tty)
clear_bot();
deinit();
flush(1);
raw_mode(0);
exit(status);
}
char *
helpfile(void)
{
return (less_is_more ? HELPDIR "/more.help" : HELPDIR "/less.help");
}