- Fix for possible unset uid/gid in toproto
 - Fix for default mtree style
 - Update libelf
 - Importing libexecinfo
 - Resynchronize GCC, mpc, gmp, mpfr
 - build.sh: Replace params with show-params.
     This has been done as the make target has been renamed in the same
     way, while a new target named params has been added. This new
     target generates a file containing all the parameters, instead of
     printing it on the console.
 - Update test48 with new etc/services (Fix by Ben Gras <ben@minix3.org)
     get getservbyport() out of the inner loop
Change-Id: Ie6ad5226fa2621ff9f0dee8782ea48f9443d2091
		
	
			
		
			
				
	
	
		
			421 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			421 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*	$NetBSD: main.c,v 1.4 2013/09/04 19:44:21 tron Exp $	*/
 | 
						|
 | 
						|
/*
 | 
						|
 * Copyright (C) 1984-2012  Mark Nudelman
 | 
						|
 *
 | 
						|
 * 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 "less.h"
 | 
						|
#if MSDOS_COMPILER==WIN32C
 | 
						|
#include <windows.h>
 | 
						|
#endif
 | 
						|
 | 
						|
public char *	every_first_cmd = NULL;
 | 
						|
public int	new_file;
 | 
						|
public int	is_tty;
 | 
						|
public IFILE	curr_ifile = NULL_IFILE;
 | 
						|
public IFILE	old_ifile = NULL_IFILE;
 | 
						|
public struct scrpos initial_scrpos;
 | 
						|
public int	any_display = FALSE;
 | 
						|
public POSITION	start_attnpos = NULL_POSITION;
 | 
						|
public POSITION	end_attnpos = NULL_POSITION;
 | 
						|
public int	wscroll;
 | 
						|
public char *	progname;
 | 
						|
public int	quitting;
 | 
						|
public int	secure;
 | 
						|
public int	dohelp;
 | 
						|
public int	more_mode = 0;
 | 
						|
 | 
						|
#if LOGFILE
 | 
						|
public int	logfile = -1;
 | 
						|
public int	force_logfile = FALSE;
 | 
						|
public char *	namelogfile = NULL;
 | 
						|
#endif
 | 
						|
 | 
						|
#if EDITOR
 | 
						|
public char *	editor;
 | 
						|
public char *	editproto;
 | 
						|
#endif
 | 
						|
 | 
						|
#if TAGS
 | 
						|
extern char *	tags;
 | 
						|
extern char *	tagoption;
 | 
						|
extern int	jump_sline;
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef WIN32
 | 
						|
static char consoleTitle[256];
 | 
						|
#endif
 | 
						|
 | 
						|
extern int	less_is_more;
 | 
						|
extern int	missing_cap;
 | 
						|
extern int	know_dumb;
 | 
						|
extern int	quit_if_one_screen;
 | 
						|
extern int	pr_type;
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Entry point.
 | 
						|
 */
 | 
						|
int
 | 
						|
main(argc, argv)
 | 
						|
	int argc;
 | 
						|
	char *argv[];
 | 
						|
{
 | 
						|
	IFILE ifile;
 | 
						|
	char *s;
 | 
						|
 | 
						|
#ifdef __EMX__
 | 
						|
	_response(&argc, &argv);
 | 
						|
	_wildcard(&argc, &argv);
 | 
						|
#endif
 | 
						|
 | 
						|
	progname = *argv++;
 | 
						|
	argc--;
 | 
						|
 | 
						|
	secure = 0;
 | 
						|
	s = lgetenv("LESSSECURE");
 | 
						|
	if (s != NULL && *s != '\0')
 | 
						|
		secure = 1;
 | 
						|
 | 
						|
#ifdef WIN32
 | 
						|
	if (getenv("HOME") == NULL)
 | 
						|
	{
 | 
						|
		/*
 | 
						|
		 * If there is no HOME environment variable,
 | 
						|
		 * try the concatenation of HOMEDRIVE + HOMEPATH.
 | 
						|
		 */
 | 
						|
		char *drive = getenv("HOMEDRIVE");
 | 
						|
		char *path  = getenv("HOMEPATH");
 | 
						|
		if (drive != NULL && path != NULL)
 | 
						|
		{
 | 
						|
			char *env = (char *) ecalloc(strlen(drive) + 
 | 
						|
					strlen(path) + 6, sizeof(char));
 | 
						|
			strcpy(env, "HOME=");
 | 
						|
			strcat(env, drive);
 | 
						|
			strcat(env, path);
 | 
						|
			putenv(env);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	GetConsoleTitle(consoleTitle, sizeof(consoleTitle)/sizeof(char));
 | 
						|
#endif /* WIN32 */
 | 
						|
 | 
						|
	/*
 | 
						|
	 * Process command line arguments and LESS environment arguments.
 | 
						|
	 * Command line arguments override environment arguments.
 | 
						|
	 */
 | 
						|
	if (strcmp(getprogname(), "more") == 0)
 | 
						|
		more_mode = 1;
 | 
						|
 | 
						|
	is_tty = isatty(1);
 | 
						|
	get_term();
 | 
						|
	init_cmds();
 | 
						|
	init_charset();
 | 
						|
	init_line();
 | 
						|
	init_cmdhist();
 | 
						|
	init_option();
 | 
						|
	init_search();
 | 
						|
 | 
						|
	/*
 | 
						|
	 * If the name of the executable program is "more",
 | 
						|
	 * act like LESS_IS_MORE is set.
 | 
						|
	 */
 | 
						|
	for (s = progname + strlen(progname);  s > progname;  s--)
 | 
						|
	{
 | 
						|
		if (s[-1] == PATHNAME_SEP[0])
 | 
						|
			break;
 | 
						|
	}
 | 
						|
	if (strcmp(s, "more") == 0)
 | 
						|
		less_is_more = 1;
 | 
						|
 | 
						|
	init_prompt();
 | 
						|
 | 
						|
	s = lgetenv(less_is_more ? "MORE" : "LESS");
 | 
						|
	if (s != NULL)
 | 
						|
		scan_option(save(s));
 | 
						|
 | 
						|
#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);
 | 
						|
	}
 | 
						|
#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 (less_is_more && get_quit_at_eof())
 | 
						|
		quit_if_one_screen = TRUE;
 | 
						|
 | 
						|
#if EDITOR
 | 
						|
	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";
 | 
						|
#endif
 | 
						|
 | 
						|
	/*
 | 
						|
	 * Call get_ifile with all the command line filenames
 | 
						|
	 * to "register" them with the ifile system.
 | 
						|
	 */
 | 
						|
	ifile = NULL_IFILE;
 | 
						|
	if (dohelp)
 | 
						|
		ifile = get_ifile(FAKE_HELPFILE, ifile);
 | 
						|
	while (argc-- > 0)
 | 
						|
	{
 | 
						|
		char *filename;
 | 
						|
#if (MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC)
 | 
						|
		/*
 | 
						|
		 * Because the "shell" doesn't expand filename patterns,
 | 
						|
		 * treat each argument as a filename pattern rather than
 | 
						|
		 * a single filename.  
 | 
						|
		 * Expand the pattern and iterate over the expanded list.
 | 
						|
		 */
 | 
						|
		struct textlist tlist;
 | 
						|
		char *gfilename;
 | 
						|
		
 | 
						|
		gfilename = lglob(*argv++);
 | 
						|
		init_textlist(&tlist, gfilename);
 | 
						|
		filename = NULL;
 | 
						|
		while ((filename = forw_textlist(&tlist, filename)) != NULL)
 | 
						|
		{
 | 
						|
			(void) get_ifile(filename, ifile);
 | 
						|
			ifile = prev_ifile(NULL_IFILE);
 | 
						|
		}
 | 
						|
		free(gfilename);
 | 
						|
#else
 | 
						|
		filename = shell_quote(*argv);
 | 
						|
		if (filename == NULL)
 | 
						|
			filename = *argv;
 | 
						|
		argv++;
 | 
						|
		(void) get_ifile(filename, ifile);
 | 
						|
		ifile = prev_ifile(NULL_IFILE);
 | 
						|
		free(filename);
 | 
						|
#endif
 | 
						|
	}
 | 
						|
	/*
 | 
						|
	 * Set up terminal, etc.
 | 
						|
	 */
 | 
						|
	if (!is_tty)
 | 
						|
	{
 | 
						|
		/*
 | 
						|
		 * Output is not a tty.
 | 
						|
		 * Just copy the input file(s) to output.
 | 
						|
		 */
 | 
						|
		SET_BINARY(1);
 | 
						|
		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 && !more_mode)
 | 
						|
		error("WARNING: terminal is not fully functional", NULL_PARG);
 | 
						|
	init_mark();
 | 
						|
	open_getchr();
 | 
						|
	raw_mode(1);
 | 
						|
	init_signals(1);
 | 
						|
 | 
						|
	/*
 | 
						|
	 * Select the first file to examine.
 | 
						|
	 */
 | 
						|
#if TAGS
 | 
						|
	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_PARG);
 | 
						|
			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 == NULL_POSITION)
 | 
						|
			quit(QUIT_ERROR);
 | 
						|
		initial_scrpos.ln = jump_sline;
 | 
						|
	} else
 | 
						|
#endif
 | 
						|
	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);
 | 
						|
	/*NOTREACHED*/
 | 
						|
	return (0);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Copy a string to a "safe" place
 | 
						|
 * (that is, to a buffer allocated by calloc).
 | 
						|
 */
 | 
						|
	public char *
 | 
						|
save(s)
 | 
						|
	char *s;
 | 
						|
{
 | 
						|
	register char *p;
 | 
						|
 | 
						|
	p = (char *) ecalloc(strlen(s)+1, sizeof(char));
 | 
						|
	strcpy(p, s);
 | 
						|
	return (p);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Allocate memory.
 | 
						|
 * Like calloc(), but never returns an error (NULL).
 | 
						|
 */
 | 
						|
	public VOID_POINTER
 | 
						|
ecalloc(count, size)
 | 
						|
	int count;
 | 
						|
	unsigned int size;
 | 
						|
{
 | 
						|
	register VOID_POINTER p;
 | 
						|
 | 
						|
	p = (VOID_POINTER) calloc(count, size);
 | 
						|
	if (p != NULL)
 | 
						|
		return (p);
 | 
						|
	error("Cannot allocate memory", NULL_PARG);
 | 
						|
	quit(QUIT_ERROR);
 | 
						|
	/*NOTREACHED*/
 | 
						|
	return (NULL);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Skip leading spaces in a string.
 | 
						|
 */
 | 
						|
	public char *
 | 
						|
skipsp(s)
 | 
						|
	register 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.
 | 
						|
 */
 | 
						|
	public int
 | 
						|
sprefix(ps, s, uppercase)
 | 
						|
	char *ps;
 | 
						|
	char *s;
 | 
						|
	int uppercase;
 | 
						|
{
 | 
						|
	register int c;
 | 
						|
	register int sc;
 | 
						|
	register int len = 0;
 | 
						|
 | 
						|
	for ( ;  *s != '\0';  s++, ps++)
 | 
						|
	{
 | 
						|
		c = *ps;
 | 
						|
		if (uppercase)
 | 
						|
		{
 | 
						|
			if (len == 0 && ASCII_IS_LOWER(c))
 | 
						|
				return (-1);
 | 
						|
			if (ASCII_IS_UPPER(c))
 | 
						|
				c = ASCII_TO_LOWER(c);
 | 
						|
		}
 | 
						|
		sc = *s;
 | 
						|
		if (len > 0 && ASCII_IS_UPPER(sc))
 | 
						|
			sc = ASCII_TO_LOWER(sc);
 | 
						|
		if (c != sc)
 | 
						|
			break;
 | 
						|
		len++;
 | 
						|
	}
 | 
						|
	return (len);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Exit the program.
 | 
						|
 */
 | 
						|
	public void
 | 
						|
quit(status)
 | 
						|
	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((char*)NULL);
 | 
						|
	save_cmdhist();
 | 
						|
	if (any_display && is_tty)
 | 
						|
		clear_bot();
 | 
						|
	deinit();
 | 
						|
	flush();
 | 
						|
	raw_mode(0);
 | 
						|
#if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC
 | 
						|
	/* 
 | 
						|
	 * If we don't close 2, we get some garbage from
 | 
						|
	 * 2's buffer when it flushes automatically.
 | 
						|
	 * I cannot track this one down  RB
 | 
						|
	 * The same bug shows up if we use ^C^C to abort.
 | 
						|
	 */
 | 
						|
	close(2);
 | 
						|
#endif
 | 
						|
#ifdef WIN32
 | 
						|
	SetConsoleTitle(consoleTitle);
 | 
						|
#endif
 | 
						|
	close_getchr();
 | 
						|
	exit(status);
 | 
						|
}
 |