[mod.sources] v06i103: New version of less

sources-request@mirror.UUCP (08/11/86)

Submitted by: seismo!lll-crg!csustan!casey
Mod.sources: Volume 6, Issue 103
Archive-name: less2/Part02

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	makefile.sys5
#	makefile.xen
#	mkfuncs.awk
#	n10-diff
#	option.c
#	output.c
#	pager_patch.c
#	position.c
#	position.h
#	prim.c
#	prompt.c
#	screen.c
#	signal.c
#	ttyin.c
#	version.c
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f 'makefile.sys5'
then
	echo shar: "will not over-write existing file 'makefile.sys5'"
else
cat << \SHAR_EOF > 'makefile.sys5'
# Makefile for "less"
#
# Invoked as:
#	make all
#   or	make install
# Plain "make" is equivalent to "make all".
#
# If you add or delete functions, remake funcs.h by doing:
#	make newfuncs
# This depends on the coding convention of function headers looking like:
#	" \t public <function-type> \n <function-name> ( ... ) "
#
# Also provided:
#	make lint	# Runs "lint" on all the sources.
#	make clean	# Removes "less" and the .o files.
#	make clobber	# Pretty much the same as make "clean".
#
#	make pager_patch		# makes PAGER environment variable
#	make install_pager_patch	# catcher and installs it (see below)


##########################################################################
# System-specific parameters
##########################################################################

# Define XENIX if running under XENIX 3.0
XENIX = 0

# VOID is 1 if your C compiler supports the "void" type,
# 0 if it does not.
VOID = 1

# off_t is the type which lseek() returns.
# It is also the type of lseek()'s second argument.
off_t = long

# TERMIO is 1 if your system has /usr/include/termio.h.
# This is normally the case for System 5.
# If TERMIO is 0 your system must have /usr/include/sgtty.h.
# This is normally the case for BSD.
TERMIO = 1

# SIGSETMASK is 1 if your system has the sigsetmask() call.
# This is normally the case only for BSD 4.2,
# not for BSD 4.1 or System 5.
SIGSETMASK = 0


##########################################################################
# Optional and semi-optional features
##########################################################################

# REGCMP is 1 if your system has the regcmp() function.
# This is normally the case for System 5.
# RECOMP is 1 if your system has the re_comp() function.
# This is normally the case for BSD.
# If neither is 1, pattern matching is supported, but without metacharacters.
REGCMP = 1
RECOMP = 0

# SHELL_ESCAPE is 1 if you wish to allow shell escapes.
# (This is possible only if your system supplies the system() function.)
SHELL_ESCAPE = 0

# EDITOR is 1 if you wish to allow editor invocation (the "v" command).
# (This is possible only if your system supplies the system() function.)
# EDIT_PGM is the name of the (default) editor to be invoked.
EDITOR = 0
EDIT_PGM = /usr/ucb/vi

# parameters to "make install_pager_patch".  OLD_PAGER will be moved to
# OLD_PAGER_NEW_LOCATION and pager_patch (in this directory) will be installed
# as OLD_PAGER.  This patch will allow you to set the environment variable
# PAGER to specify your personal pager preference (is this a security hole?)
OLD_PAGER = /usr/ucb/more
OLD_PAGER_NEW_LOCATION = /usr/ucb/More

# ONLY_RETURN is 1 if you want RETURN to be the only input which
# will continue past an error message.
# Otherwise, any key will continue past an error message.
ONLY_RETURN = 0


##########################################################################
# Compilation environment.
##########################################################################

# LIBS is the list of libraries needed.
LIBS = -lcurses -lPW

# INSTALL_LESS is a list of the public versions of less.
# INSTALL_MAN is a list of the public versions of the manual page.
INSTALL_LESS =	/usr/lbin/less
INSTALL_MAN =	/usr/man/manl/less.l

# OPTIM is passed to the compiler and the loader.
# It is normally "-O" but may be, for example, "-g".
OPTIM = -O


##########################################################################
# Files
##########################################################################

SRC1 =	main.c option.c prim.c 
SRC2 =	ch.c position.c input.c output.c screen.c \
	prompt.c line.c signal.c help.c ttyin.c command.c version.c
SRC =	$(SRC1) $(SRC2)
OBJ =	main.o option.o prim.o ch.o position.o input.o output.o screen.o \
	prompt.o line.o signal.o help.o ttyin.o command.o version.o


##########################################################################
# Rules
##########################################################################

DEFS =	"-DTERMIO=$(TERMIO)" \
	"-DSIGSETMASK=$(SIGSETMASK)" \
	"-Doff_t=$(off_t)" "-DVOID=$(VOID)" \
	"-DREGCMP=$(REGCMP)" "-DRECOMP=$(RECOMP)" \
	"-DSHELL_ESCAPE=$(SHELL_ESCAPE)" \
	"-DEDITOR=$(EDITOR)" "-DEDIT_PGM=\"$(EDIT_PGM)\"" \
	"-DONLY_RETURN=$(ONLY_RETURN)" \
	"-DXENIX=$(XENIX)" \
	"-DOLD_PAGER_NEW_LOCATION=\"$(OLD_PAGER_NEW_LOCATION)\""

CFLAGS = $(OPTIM) $(DEFS)


all: less

less: $(OBJ)
	cc $(OPTIM) -o less $(OBJ) $(LIBS)

install: install_man install_less

install_man: less.l
	for f in $(INSTALL_MAN); do  rm -f $$f; cp less.l $$f;  done
	touch install_man
	
install_less: less
	for f in $(INSTALL_LESS); do  rm -f $$f; cp less $$f;  done
	touch install_less

pager_patch: pager_patch.c
	cc $(CFLAGS) -s -o pager_patch pager_patch.c

install_pager_patch: pager_patch
	if [ -s $(OLD_PAGER) -a ! -s $(OLD_PAGER_NEW_LOCATION) ]; then \
		mv $(OLD_PAGER) $(OLD_PAGER_NEW_LOCATION); \
		cp pager_patch $(OLD_PAGER); \
	fi
	touch install_pager_patch

$(OBJ): less.h funcs.h

lint:
	lint -hp $(DEFS) $(SRC)

newfuncs:
	mv funcs.h funcs.h.OLD
	awk -f mkfuncs.awk $(SRC) >funcs.h

clean:
	rm -f $(OBJ) less pager_patch

clobber:
	rm -f *.o less pager_patch install_less install_man install_pager_patch

shar:
	shar -v INSTALLATION less.l makefile.* *.h *.awk $(SRC1) > less.shar.a
	shar -v $(SRC2) pager_patch.c > less.shar.b
SHAR_EOF
fi
if test -f 'makefile.xen'
then
	echo shar: "will not over-write existing file 'makefile.xen'"
else
cat << \SHAR_EOF > 'makefile.xen'
# Makefile for "less"
#
# Invoked as:
#	make all
#   or	make install
# Plain "make" is equivalent to "make all".
#
# If you add or delete functions, remake funcs.h by doing:
#	make newfuncs
# This depends on the coding convention of function headers looking like:
#	" \t public <function-type> \n <function-name> ( ... ) "
#
# Also provided:
#	make lint	# Runs "lint" on all the sources.
#	make clean	# Removes "less" and the .o files.
#	make clobber	# Pretty much the same as make "clean".
#
#	make pager_patch		# makes PAGER environment variable
#	make install_pager_patch	# catcher and installs it (see below)


##########################################################################
# System-specific parameters
##########################################################################

# Define XENIX if running under XENIX 3.0
XENIX = 1

# VOID is 1 if your C compiler supports the "void" type,
# 0 if it does not.
VOID = 1

# off_t is the type which lseek() returns.
# It is also the type of lseek()'s second argument.
off_t = long

# TERMIO is 1 if your system has /usr/include/termio.h.
# This is normally the case for System 5.
# If TERMIO is 0 your system must have /usr/include/sgtty.h.
# This is normally the case for BSD.
TERMIO = 1

# SIGSETMASK is 1 if your system has the sigsetmask() call.
# This is normally the case only for BSD 4.2,
# not for BSD 4.1 or System 5.
SIGSETMASK = 0


##########################################################################
# Optional and semi-optional features
##########################################################################

# REGCMP is 1 if your system has the regcmp() function.
# This is normally the case for System 5.
# RECOMP is 1 if your system has the re_comp() function.
# This is normally the case for BSD.
# If neither is 1, pattern matching is supported, but without metacharacters.
REGCMP = 1
RECOMP = 0

# SHELL_ESCAPE is 1 if you wish to allow shell escapes.
# (This is possible only if your system supplies the system() function.)
SHELL_ESCAPE = 0

# EDITOR is 1 if you wish to allow editor invocation (the "v" command).
# (This is possible only if your system supplies the system() function.)
# EDIT_PGM is the name of the (default) editor to be invoked.
EDITOR = 0
EDIT_PGM = /usr/ucb/vi

# parameters to "make install_pager_patch".  OLD_PAGER will be moved to
# OLD_PAGER_NEW_LOCATION and pager_patch (in this directory) will be installed
# as OLD_PAGER.  This patch will allow you to set the environment variable
# PAGER to specify your personal pager preference (is this a security hole?)
OLD_PAGER = /usr/ucb/more
OLD_PAGER_NEW_LOCATION = /usr/ucb/More

# ONLY_RETURN is 1 if you want RETURN to be the only input which
# will continue past an error message.
# Otherwise, any key will continue past an error message.
ONLY_RETURN = 0


##########################################################################
# Compilation environment.
##########################################################################

# LIBS is the list of libraries needed.
LIBS = -lcurses -ltermlib

# INSTALL_LESS is a list of the public versions of less.
# INSTALL_MAN is a list of the public versions of the manual page.
INSTALL_LESS =	/usr/lbin/less
INSTALL_MAN =	/usr/man/manl/less.l

# OPTIM is passed to the compiler and the loader.
# It is normally "-O" but may be, for example, "-g".
OPTIM = -O


##########################################################################
# Files
##########################################################################

SRC1 =	main.c option.c prim.c 
SRC2 =	ch.c position.c input.c output.c screen.c \
	prompt.c line.c signal.c help.c ttyin.c command.c version.c
SRC =	$(SRC1) $(SRC2)
OBJ =	main.o option.o prim.o ch.o position.o input.o output.o screen.o \
	prompt.o line.o signal.o help.o ttyin.o command.o version.o


##########################################################################
# Rules
##########################################################################

DEFS =	"-DTERMIO=$(TERMIO)" \
	"-DSIGSETMASK=$(SIGSETMASK)" \
	"-Doff_t=$(off_t)" "-DVOID=$(VOID)" \
	"-DREGCMP=$(REGCMP)" "-DRECOMP=$(RECOMP)" \
	"-DSHELL_ESCAPE=$(SHELL_ESCAPE)" \
	"-DEDITOR=$(EDITOR)" "-DEDIT_PGM=\"$(EDIT_PGM)\"" \
	"-DONLY_RETURN=$(ONLY_RETURN)" \
	"-DXENIX=$(XENIX)" \
	"-DOLD_PAGER_NEW_LOCATION=\"$(OLD_PAGER_NEW_LOCATION)\""

CFLAGS = $(OPTIM) $(DEFS)


all: less

less: $(OBJ)
	cc $(OPTIM) -o less $(OBJ) $(LIBS)

install: install_man install_less

install_man: less.l
	for f in $(INSTALL_MAN); do  rm -f $$f; cp less.l $$f;  done
	touch install_man
	
install_less: less
	for f in $(INSTALL_LESS); do  rm -f $$f; cp less $$f;  done
	touch install_less

pager_patch: pager_patch.c
	cc $(CFLAGS) -s -o pager_patch pager_patch.c

install_pager_patch: pager_patch
	if [ -s $(OLD_PAGER) -a ! -s $(OLD_PAGER_NEW_LOCATION) ]; then \
		mv $(OLD_PAGER) $(OLD_PAGER_NEW_LOCATION); \
		cp pager_patch $(OLD_PAGER); \
	fi
	touch install_pager_patch

$(OBJ): less.h funcs.h

lint:
	lint -hp $(DEFS) $(SRC)

newfuncs:
	mv funcs.h funcs.h.OLD
	awk -f mkfuncs.awk $(SRC) >funcs.h

clean:
	rm -f $(OBJ) less pager_patch

clobber:
	rm -f *.o less pager_patch install_less install_man install_pager_patch

shar:
	shar -v INSTALLATION less.l makefile.* *.h *.awk $(SRC1) > less.shar.a
	shar -v $(SRC2) pager_patch.c > less.shar.b
SHAR_EOF
fi
if test -f 'mkfuncs.awk'
then
	echo shar: "will not over-write existing file 'mkfuncs.awk'"
else
cat << \SHAR_EOF > 'mkfuncs.awk'
BEGIN { FS="("; state = 0 }

/^	public/ { ftype = $0; state = 1 }

{ if (state == 1)
	state = 2
  else if (state == 2)
	{ print ftype,$1,"();"; state = 0 }
}
SHAR_EOF
fi
if test -f 'n10-diff'
then
	echo shar: "will not over-write existing file 'n10-diff'"
else
cat << \SHAR_EOF > 'n10-diff'
*** n10-old.c	Sun May  4 01:45:06 1986
--- n10.c	Mon Jul 14 12:27:54 1986
***************
*** 137,151
  	if(*codep && (esc || lead))move();
  	esct += w;
  	if(i&074000)xfont = (i>>9) & 03;
! 	if(*t.bdon & 0377){
! 		if(!bdmode && (xfont == 2)){
! 			oputs(t.bdon);
! 			bdmode++;
! 		}
! 		if(bdmode && (xfont != 2)){
! 			oputs(t.bdoff);
! 			bdmode = 0;
! 		}
  	}
  	if(xfont == ulfont){
  		for(k=w/t.Char;k>0;k--)oput('_');

--- 137,145 -----
  	if(*codep && (esc || lead))move();
  	esct += w;
  	if(i&074000)xfont = (i>>9) & 03;
! 	if(!bdmode && (xfont == 2)){
! 		if(*t.bdon & 0377)oputs(t.bdon);
! 		bdmode++;
  	}
  	if(bdmode && (xfont != 2)){
  		if(*t.bdoff & 0377)oputs(t.bdoff);
***************
*** 147,152
  			bdmode = 0;
  		}
  	}
  	if(xfont == ulfont){
  		for(k=w/t.Char;k>0;k--)oput('_');
  		for(k=w/t.Char;k>0;k--)oput('\b');

--- 141,150 -----
  		if(*t.bdon & 0377)oputs(t.bdon);
  		bdmode++;
  	}
+ 	if(bdmode && (xfont != 2)){
+ 		if(*t.bdoff & 0377)oputs(t.bdoff);
+ 		bdmode = 0;
+ 	}
  	if(xfont == ulfont){
  		for(k=w/t.Char;k>0;k--)oput('_');
  		for(k=w/t.Char;k>0;k--)oput('\b');
***************
*** 158,163
  			oput(' ');
  		}else{
  			if(plotmode)oputs(t.plotoff);
  			*obufp++ = *codep++;
  			if(obufp == (obuf + OBUFSZ + ascii - 1))flusho();
  /*			oput(*codep++);*/

--- 156,162 -----
  			oput(' ');
  		}else{
  			if(plotmode)oputs(t.plotoff);
+ 			if(obufp >= (obuf + OBUFSZ + ascii - 1 - (bdmode?3:1)))flusho();
  			*obufp++ = *codep++;
  			if(bdmode && !*t.bdon){
  				*obufp++ = '\b';
***************
*** 159,165
  		}else{
  			if(plotmode)oputs(t.plotoff);
  			*obufp++ = *codep++;
! 			if(obufp == (obuf + OBUFSZ + ascii - 1))flusho();
  /*			oput(*codep++);*/
  		}
  	}

--- 158,167 -----
  			if(plotmode)oputs(t.plotoff);
  			if(obufp >= (obuf + OBUFSZ + ascii - 1 - (bdmode?3:1)))flusho();
  			*obufp++ = *codep++;
! 			if(bdmode && !*t.bdon){
! 				*obufp++ = '\b';
! 				*obufp++ = codep[-1];
! 			}
  /*			oput(*codep++);*/
  		}
  	}
SHAR_EOF
fi
if test -f 'option.c'
then
	echo shar: "will not over-write existing file 'option.c'"
else
cat << \SHAR_EOF > 'option.c'
/*
 * Process command line options.
 * Each option is a single letter which controls a program variable.
 * The options have defaults which may be changed via
 * the command line option, or toggled via the "-" command.
 */

#include "less.h"

#define	toupper(c)	((c)-'a'+'A')

/*
 * Types of options.
 */
#define	BOOL		01	/* Boolean option: 0 or 1 */
#define	TRIPLE		02	/* Triple-valued option: 0, 1 or 2 */
#define	NUMBER		04	/* Numeric option */
#define	NO_TOGGLE	0100	/* Option cannot be toggled with "-" cmd */

/*
 * Variables controlled by command line options.
 */
public int p_nbufs, f_nbufs;	/* Number of buffers.  There are two values,
				   one used for input from a pipe and 
				   the other for input from a file. */
public int clean_data;		/* Can we assume the data is "clean"? 
				   (That is, free of nulls, etc) */
public int quiet;		/* Should we suppress the audible bell? */
public int top_search;		/* Should forward searches start at the top 
				   of the screen? (alternative is bottom) */
public int top_scroll;		/* Repaint screen from top?
				   (alternative is scroll from bottom) */
public int pr_type;		/* Type of prompt (short, medium, long) */
public int bs_mode;		/* How to process backspaces */
public int know_dumb;		/* Don't complain about dumb terminals */
public int quit_at_eof;		/* Quit after hitting end of file twice */
public int squeeze;		/* Squeeze multiple blank lines into one */
public int tabstop;		/* Tab settings */
public int back_scroll;		/* Repaint screen on backwards movement */
public int twiddle;		/* Display "~" for lines after EOF */

extern int nbufs;
extern int sc_window;
extern char *first_cmd;
extern char *every_first_cmd;

#define	DEF_F_NBUFS	5	/* Default for f_nbufs */
#define	DEF_P_NBUFS	12	/* Default for p_nbufs */

static struct option
{
	char oletter;		/* The controlling letter (a-z) */
	char otype;		/* Type of the option */
	int odefault;		/* Default value */
	int *ovar;		/* Pointer to the associated variable */
	char *odesc[3];		/* Description of each value */
} option[] =
{
	{ 'c', BOOL, 0, &clean_data,
		{ "Don't assume data is clean",
		  "Assume data is clean",
		  NULL
		}
	},
	{ 'd', BOOL|NO_TOGGLE, 0, &know_dumb,
		{ NULL, NULL, NULL}
	},
	{ 'e', BOOL, 0, &quit_at_eof,
		{ "Don't quit at end-of-file",
		  "Quit at end-of-file",
		  NULL
		}
	},
	{ 'h', NUMBER, -1, &back_scroll,
		{ "Backwards scroll limit is %d lines",
		  NULL, NULL
		}
	},
	{ 'p', BOOL, 0, &top_scroll,
		{ "Repaint by scrolling from bottom of screen",
		  "Repaint by painting from top of screen",
		  NULL
		}
	},
	{ 'x', NUMBER, 8, &tabstop,
		{ "Tab stops every %d spaces", 
		  NULL, NULL 
		}
	},
	{ 's', BOOL, 0, &squeeze,
		{ "Don't squeeze multiple blank lines",
		  "Squeeze multiple blank lines",
		  NULL
		}
	},
	{ 't', BOOL, 1, &top_search,
		{ "Forward search starts from bottom of screen",
		  "Forward search starts from top of screen",
		  NULL
		}
	},
	{ 'w', BOOL, 1, &twiddle,
		{ "Display nothing for lines after end-of-file",
		  "Display ~ for lines after end-of-file",
		  NULL
		}
	},
	{ 'm', TRIPLE, 0, &pr_type,
		{ "Prompt with a colon",
		  "Prompt with a message",
		  "Prompt with a verbose message"
		}
	},
	{ 'q', TRIPLE, 0, &quiet,
		{ "Ring the bell for errors AND at eof/bof",
		  "Ring the bell for errors but not at eof/bof",
		  "Never ring the bell"
		}
	},
	{ 'u', TRIPLE, 0, &bs_mode,
		{ "Underlined text displayed in underline mode",
		  "All backspaces cause overstrike",
		  "Backspaces print as ^H"
		}
	},
	{ 'z', NUMBER, 24, &sc_window,
		{ "Scroll window size is %d lines",
		  NULL, NULL
		}
	},
	{ '\0' }
};

public char all_options[64];	/* List of all valid options */

/*
 * Initialize each option to its default value.
 */
	public void
init_option()
{
	register struct option *o;
	register char *p;

	/*
	 * First do special cases, not in option table.
	 */
	first_cmd = every_first_cmd = NULL;
	f_nbufs = DEF_F_NBUFS;		/* -bf */
	p_nbufs = DEF_P_NBUFS;		/* -bp */

	p = all_options;
	*p++ = 'b';

	for (o = option;  o->oletter != '\0';  o++)
	{
		/*
		 * Set each variable to its default.
		 * Also make a list of all options, in "all_options".
		 */
		*(o->ovar) = o->odefault;
		*p++ = o->oletter;
		if (o->otype & TRIPLE)
			*p++ = toupper(o->oletter);
	}
	*p = '\0';
}

/*
 * Toggle command line flags from within the program.
 * Used by the "-" command.
 */
	public void
toggle_option(c)
	int c;
{
	register struct option *o;
	char message[100];
	char buf[5];

	/*
	 * First check for special cases not handled by the option table.
	 */
	switch (c)
	{
	case 'b':
		sprintf(message, "%d buffers", nbufs);
		error(message);
		return;
	}


	for (o = option;  o->oletter != '\0';  o++)
	{
		if ((o->otype & BOOL) && (o->oletter == c) &&
			(o->otype & NO_TOGGLE) == 0)
		{
			/*
			 * Boolean option: 
			 * just toggle it.
			 */
			*(o->ovar) = ! *(o->ovar);
			error(o->odesc[*(o->ovar)]);
			return;
		} else if ((o->otype & TRIPLE) && (o->oletter == c) &&
			(o->otype & NO_TOGGLE) == 0)
		{
			/*
			 * Triple-valued option with lower case letter:
			 * make it 1 unless already 1, then make it 0.
			 */
			*(o->ovar) = (*(o->ovar) == 1) ? 0 : 1;
			error(o->odesc[*(o->ovar)]);
			return;
		} else if ((o->otype & TRIPLE) && (toupper(o->oletter) == c) &&
			(o->otype & NO_TOGGLE) == 0)
		{
			/*
			 * Triple-valued option with upper case letter:
			 * make it 2 unless already 2, then make it 0.
			 */
			*(o->ovar) = (*(o->ovar) == 2) ? 0 : 2;
			error(o->odesc[*(o->ovar)]);
			return;
		} else if ((o->otype & NUMBER) && (o->oletter == c) &&
			(o->otype & NO_TOGGLE) == 0)
		{
			sprintf(message, o->odesc[0], *(o->ovar));
			error(message);
			return;
		}
	}

	if (control_char(c))
		sprintf(buf, "^%c", carat_char(c));
	else
		sprintf(buf, "%c", c);
	sprintf(message, "\"-%s\": no such flag.  Use one of \"%s\"", 
		buf, all_options);
	error(message);
}

/*
 * Scan an argument (either from command line or from LESS environment 
 * variable) and process it.
 */
	public void
scan_option(s)
	char *s;
{
	register struct option *o;
	register int c;

	if (s == NULL)
		return;

    next:
	if (*s == '\0')
		return;
	switch (c = *s++)
	{
	case '-':
	case ' ':
	case '\t':
		goto next;
	case '+':
		if (*s == '+')
			every_first_cmd = ++s;
		first_cmd = s;
		return;
	case 'b':
		switch (*s)
		{
		case 'f':
			s++;
			f_nbufs = getnum(&s, 'b');
			break;
		case 'p':
			s++;
			p_nbufs = getnum(&s, 'b');
			break;
		default:
			f_nbufs = p_nbufs = getnum(&s, 'b');
			break;
		}
		goto next;
	case '0':  case '1':  case '2':  case '3':  case '4':
	case '5':  case '6':  case '7':  case '8':  case '9':
		{
			/*
			 * Handle special "more" compatibility form "-number"
			 * to set the scrolling window size.
			 */
			s--;
			sc_window = getnum(&s, '-');
			goto next;
		}
	}

	for (o = option;  o->oletter != '\0';  o++)
	{
		if ((o->otype & BOOL) && (o->oletter == c))
		{
			*(o->ovar) = ! o->odefault;
			goto next;
		} else if ((o->otype & TRIPLE) && (o->oletter == c))
		{
			*(o->ovar) = (o->odefault == 1) ? 0 : 1;
			goto next;
		} else if ((o->otype & TRIPLE) && (toupper(o->oletter) == c))
		{
			*(o->ovar) = (o->odefault == 2) ? 0 : 2;
			goto next;
		} else if ((o->otype & NUMBER) && (o->oletter == c))
		{
			*(o->ovar) = getnum(&s, c);
			goto next;
		}
	}

	printf("\"-%c\": invalid flag\n", c);
	exit(1);
}

/*
 * Translate a string into a number.
 * Like atoi(), but takes a pointer to a char *, and updates
 * the char * to point after the translated number.
 */
	static int
getnum(sp, c)
	char **sp;
	int c;
{
	register char *s;
	register int n;

	s = *sp;
	if (*s < '0' || *s > '9')
	{
		printf("number is required after -%c\n", c);
		exit(1);
	}

	n = 0;
	while (*s >= '0' && *s <= '9')
		n = 10 * n + *s++ - '0';
	*sp = s;
	return (n);
}
SHAR_EOF
fi
if test -f 'output.c'
then
	echo shar: "will not over-write existing file 'output.c'"
else
cat << \SHAR_EOF > 'output.c'
/*
 * High level routines dealing with the output to the screen.
 */

#include "less.h"

extern int sigs;
extern int sc_width, sc_height;
extern int bo_width, be_width;
extern int ul_width, ue_width;
extern int so_width, se_width;
extern int tabstop;
extern int twiddle;
extern char *line;
extern char *first_cmd;

/*
 * Display the line which is in the line buffer.
 */
	public void
put_line()
{
	register char *p;
	register int c;
	register int column;
	extern int auto_wrap, ignaw;

	if (sigs)
		/*
		 * Don't output if a signal is pending.
		 */
		return;

	if (line == NULL)
		line = (twiddle) ? "~" : "";

	column = 0;
	for (p = line;  *p != '\0';  p++)
	{
		switch (c = *p)
		{
		case UL_CHAR:
			ul_enter();
			column += ul_width;
			break;
		case UE_CHAR:
			ul_exit();
			column += ue_width;
			break;
		case BO_CHAR:
			bo_enter();
			column += bo_width;
			break;
		case BE_CHAR:
			bo_exit();
			column += be_width;
			break;
		case '\t':
			do
			{
				putc(' ');
				column++;
			} while ((column % tabstop) != 0);
			break;
		case '\b':
			putbs();
			column--;
			break;
		default:
			if (c & 0200)
			{
				putc('^');
				putc(c & 0177);
				column += 2;
			} else
			{
				putc(c);
				column++;
			}
		}
	}
	if (column < sc_width || !auto_wrap || ignaw)
		putc('\n');
}

/*
 * Is a given character a "control" character?
 * {{ ASCII DEPENDENT }}
 */
	public int
control_char(c)
	int c;
{
	return (c < ' ' || c == '\177');
}

/*
 * Return the printable character used to identify a control character
 * (printed after a carat; e.g. '\3' => "^C").
 * {{ ASCII DEPENDENT }}
 */
	public int
carat_char(c)
	int c;
{
	return ((c == '\177') ? '?' : (c | 0100));
}


static char obuf[1024];
static char *ob = obuf;

/*
 * Flush buffered output.
 */
	public void
flush()
{
	write(1, obuf, ob-obuf);
	ob = obuf;
}

/*
 * Discard buffered output.
 */
	public void
dropout()
{
	ob = obuf;
}

/*
 * Output a character.
 */
	public void
putc(c)
	int c;
{
	if (ob >= &obuf[sizeof(obuf)])
		flush();
	*ob++ = c;
}

/*
 * Output a string.
 */
	public void
puts(s)
	register char *s;
{
	while (*s != '\0')
		putc(*s++);
}

/*
 * Output a message in the lower left corner of the screen
 * and wait for carriage return.
 */

static char return_to_continue[] = "  (press RETURN)";

	public void
error(s)
	char *s;
{
	register int c;
	static char buf[2];

	lower_left();
	clear_eol();
	so_enter();
	puts(s);
	puts(return_to_continue);
	so_exit();

#if ONLY_RETURN
	while ((c = getc()) != '\n' && c != '\r')
		bell();
#else
	c = getc();
	if (c != '\n' && c != '\r' && c != ' ')
	{
		buf[0] = c;
		first_cmd = buf;
	}
#endif

	if (strlen(s) > sc_width)
		repaint();
}

	public int
error_width()
{
	/*
	 * Don't use the last position, because some terminals
	 * will scroll if you write in the last char of the last line.
	 */
	return (sc_width - 
		(sizeof(return_to_continue) + so_width + se_width + 1));
}
SHAR_EOF
fi
if test -f 'pager_patch.c'
then
	echo shar: "will not over-write existing file 'pager_patch.c'"
else
cat << \SHAR_EOF > 'pager_patch.c'
/*
 * Special interface that checks for the environment variable PAGER.  If
 * present, the program specified is executed, otherwise OLD_PAGER_NEW_LOCATION
 * (specified below).  This program should replace /usr/ucb/more (or whatever
 * your default pager is) and more should be moved to OLD_PAGER_NEW_LOCATION.
 * This is essentially a fix for all the programs which *should* check for the
 * environment variable PAGER, but don't - hopefully it will be obsoleted as
 * old programs are update to check for PAGER so we can loose the overhead of
 * reexecuting even this small program ...
 *
 * Casey Leedom (lll-crg.arpa!csustan!casey) - 5/29/86
 */

#ifndef OLD_PAGER_NEW_LOCATION
#	define	OLD_PAGER_NEW_LOCATION	"/usr/ucb/More"
#endif !OLD_PAGER_NEW_LOCATION

void
main(argc, argv)
	int	argc;
	char	**argv;
{
	char	*pager, *getenv();

	if (!(pager = getenv("PAGER")))
		pager = OLD_PAGER_NEW_LOCATION;
	(void) execv(pager, argv);
}
SHAR_EOF
fi
if test -f 'position.c'
then
	echo shar: "will not over-write existing file 'position.c'"
else
cat << \SHAR_EOF > 'position.c'
/*
 * Routines dealing with the "position" table.
 * This is a table which tells the position (in the input file) of the
 * first char on each currently displayed line.
 *
 * {{ The position table is scrolled by moving all the entries.
 *    Would be better to have a circular table 
 *    and just change a couple of pointers. }}
 */

#include "less.h"
#include "position.h"

#define	NPOS	100		/* {{ sc_height must be less than NPOS }} */
static POSITION table[NPOS];	/* The position table */

extern int sc_width, sc_height;

/*
 * Return the position of one of:
 *	the top (first) line on the screen
 *	the second line on the screen
 *	the bottom line on the screen
 *	the line after the bottom line on the screen
 */
	public POSITION
position(where)
	int where;
{
	switch (where)
	{
	case BOTTOM:
		where = sc_height - 2;
		break;
	case BOTTOM_PLUS_ONE:
		where = sc_height - 1;
		break;
	}
	return (table[where]);
}

/*
 * Add a new file position to the bottom of the position table.
 */
	public void
add_forw_pos(pos)
	POSITION pos;
{
	register int i;

	/*
	 * Scroll the position table up.
	 */
	for (i = 1;  i < sc_height;  i++)
		table[i-1] = table[i];
	table[sc_height - 1] = pos;
}

/*
 * Add a new file position to the top of the position table.
 */
	public void
add_back_pos(pos)
	POSITION pos;
{
	register int i;

	/*
	 * Scroll the position table down.
	 */
	for (i = sc_height - 1;  i > 0;  i--)
		table[i] = table[i-1];
	table[0] = pos;
}

/*
 * Initialize the position table, done whenever we clear the screen.
 */
	public void
pos_clear()
{
	register int i;

	for (i = 0;  i < sc_height;  i++)
		table[i] = NULL_POSITION;
}

/*
 * See if the byte at a specified position is currently on the screen.
 * Check the position table to see if the position falls within its range.
 * Return the position table entry if found, -1 if not.
 */
	public int
onscreen(pos)
	POSITION pos;
{
	register int i;

	if (pos < table[0])
		return (-1);
	for (i = 1;  i < sc_height;  i++)
		if (pos < table[i])
			return (i-1);
	return (-1);
}
SHAR_EOF
fi
if test -f 'position.h'
then
	echo shar: "will not over-write existing file 'position.h'"
else
cat << \SHAR_EOF > 'position.h'
/*
 * Include file for interfacing to position.c modules.
 */
#define	TOP		0
#define	TOP_PLUS_ONE	1
#define	BOTTOM		-1
#define	BOTTOM_PLUS_ONE	-2
SHAR_EOF
fi
if test -f 'prim.c'
then
	echo shar: "will not over-write existing file 'prim.c'"
else
cat << \SHAR_EOF > 'prim.c'
/*
 * Primitives for displaying the file on the screen.
 */

#include "less.h"
#include "position.h"

public int hit_eof;	/* Keeps track of how many times we hit end of file */

extern int quiet;
extern int top_search;
extern int top_scroll;
extern int back_scroll;
extern int sc_width, sc_height;
extern int sigs;
extern char *line;
extern char *first_cmd;

/*
 * Sound the bell to indicate he is trying to move past end of file.
 */
	static void
eof_bell()
{
	if (quiet == NOT_QUIET)
		bell();
	else
		vbell();
}

/*
 * Check to see if the end of file is currently "displayed".
 */
	static void
eof_check()
{
	POSITION pos;

	/*
	 * If the bottom line is empty, we are at EOF.
	 * If the bottom line ends at the file length,
	 * we must be just at EOF.
	 */
	pos = position(BOTTOM_PLUS_ONE);
	if (pos == NULL_POSITION || pos == ch_length())
		hit_eof++;
}

/*
 * Display n lines, scrolling forward, 
 * starting at position pos in the input file.
 * "force" means display the n lines even if we hit end of file.
 * "only_last" means display only the last screenful if n > screen size.
 */
	static void
forw(n, pos, force, only_last)
	register int n;
	POSITION pos;
	int force;
	int only_last;
{
	int eof = 0;
	int nlines = 0;
	int repaint_flag;

	/*
	 * repaint_flag tells us not to display anything till the end, 
	 * then just repaint the entire screen.
	 */
	repaint_flag = (only_last && n > sc_height-1);

	if (!repaint_flag)
	{
		if (top_scroll && n >= sc_height - 1)
		{
			/*
			 * Start a new screen.
			 * {{ This is not really desirable if we happen
			 *    to hit eof in the middle of this screen,
			 *    but we don't know if that will happen now. }}
			 */
			clear();
			home();
			force = 1;
		} else
		{
			lower_left();
			clear_eol();
		}

		if (pos != position(BOTTOM_PLUS_ONE))
		{
			/*
			 * This is not contiguous with what is
			 * currently displayed.  Clear the screen image 
			 * (position table) and start a new screen.
			 */
			pos_clear();
			add_forw_pos(pos);
			force = 1;
			if (top_scroll)
			{
				clear();
				home();
			} else
			{
				puts("...skipping...\n");
			}
		}
	}

	while (--n >= 0)
	{
		/*
		 * Read the next line of input.
		 */
		pos = forw_line(pos);
		if (pos == NULL_POSITION)
		{
			/*
			 * End of file: stop here unless the top line 
			 * is still empty, or "force" is true.
			 */
			eof = 1;
			if (!force && position(TOP) != NULL_POSITION)
				break;
			line = NULL;
		}
		/*
		 * Add the position of the next line to the position table.
		 * Display the current line on the screen.
		 */
		add_forw_pos(pos);
		nlines++;
		if (!repaint_flag)
			put_line();
	}

	if (eof)
		hit_eof++;
	else
		eof_check();
	if (nlines == 0)
		eof_bell();
	else if (repaint_flag)
		repaint();
}

/*
 * Display n lines, scrolling backward.
 */
	static void
back(n, pos, force, only_last)
	register int n;
	POSITION pos;
	int force;
	int only_last;
{
	int nlines = 0;
	int repaint_flag;

	repaint_flag = (n > back_scroll || (only_last && n > sc_height-1));
	hit_eof = 0;
	while (--n >= 0)
	{
		/*
		 * Get the previous line of input.
		 */
		pos = back_line(pos);
		if (pos == NULL_POSITION)
		{
			/*
			 * Beginning of file: stop here unless "force" is true.
			 */
			if (!force)
				break;
			line = NULL;
		}
		/*
		 * Add the position of the previous line to the position table.
		 * Display the line on the screen.
		 */
		add_back_pos(pos);
		nlines++;
		if (!repaint_flag)
		{
			home();
			add_line();
			put_line();
		}
	}

	eof_check();
	if (nlines == 0)
		eof_bell();
	else if (repaint_flag)
		repaint();
}

/*
 * Display n more lines, forward.
 * Start just after the line currently displayed at the bottom of the screen.
 */
	public void
forward(n, only_last)
	int n;
	int only_last;
{
	POSITION pos;

	pos = position(BOTTOM_PLUS_ONE);
	if (pos == NULL_POSITION)
	{
		eof_bell();
		hit_eof++;
		return;
	}
	forw(n, pos, 0, only_last);
}

/*
 * Display n more lines, backward.
 * Start just before the line currently displayed at the top of the screen.
 */
	public void
backward(n, only_last)
	int n;
	int only_last;
{
	POSITION pos;

	pos = position(TOP);
	if (pos == NULL_POSITION)
	{
		/* 
		 * This will almost never happen,
		 * because the top line is almost never empty. 
		 */
		eof_bell();
		return;   
	}
	back(n, pos, 0, only_last);
}

/*
 * Repaint the screen, starting from a specified position.
 */
	static void
prepaint(pos)	
	POSITION pos;
{
	hit_eof = 0;
	forw(sc_height-1, pos, 0, 0);
}

/*
 * Repaint the screen.
 */
	public void
repaint()
{
	/*
	 * Start at the line currently at the top of the screen
	 * and redisplay the screen.
	 */
	prepaint(position(TOP));
}

/*
 * Jump to the end of the file.
 * It is more convenient to paint the screen backward,
 * from the end of the file toward the beginning.
 */
	public void
jump_forw()
{
	POSITION pos;

	if (ch_end_seek())
	{
		error("Cannot seek to end of file");
		return;
	}
	pos = ch_tell();
	clear();
	pos_clear();
	add_back_pos(pos);
	back(sc_height - 1, pos, 0, 0);
}

/*
 * Jump to line n in the file.
 */
	public void
jump_back(n)
	register int n;
{
	register int c;

	/*
	 * This is done the slow way, by starting at the beginning
	 * of the file and counting newlines.
	 */
	if (ch_seek((POSITION)0))
	{
		/* 
		 * Probably a pipe with beginning of file no longer buffered. 
		 */
		error("Cannot get to beginning of file");
		return;
	}

	/*
	 * Start counting lines.
	 */
	while (--n > 0)
	{
		while ((c = ch_forw_get()) != '\n')
			if (c == EOF)
			{
				error("File is not that long");
				/* {{ Maybe tell him how long it is? }} */
				return;
			}
	}

	/*
	 * Finally found the place to start.
	 * Clear and redisplay the screen from there.
	 *
	 * {{ We *could* figure out if the new position is 
	 *    close enough to just scroll there without clearing
	 *    the screen, but it's not worth it. }}
	 */
	prepaint(ch_tell());
}

/*
 * Jump to a specified percentage into the file.
 * This is a poor compensation for not being able to
 * quickly jump to a specific line number.
 */
	public void
jump_percent(percent)
	int percent;
{
	POSITION pos, len;

	/*
	 * Determine the position in the file
	 * (the specified percentage of the file's length).
	 */
	if ((len = ch_length()) == NULL_POSITION)
	{
		error("Don't know length of file");
		return;
	}
	pos = (percent * len) / 100;
	jump_loc(pos);
}

	public void
jump_loc(pos)
	POSITION pos;
{
	register int c;
	register int nline;
	POSITION tpos;

	/*
	 * See if the desired line is BEFORE the currently
	 * displayed screen.  If so, see if it is close enough 
	 * to scroll backwards to it.
	 */
	tpos = position(TOP);
	if (pos < tpos)
	{
		for (nline = 1;  nline <= back_scroll;  nline++)
		{
			tpos = back_line(tpos);
			if (tpos == NULL_POSITION || tpos <= pos)
			{
				back(nline, position(TOP), 1, 0);
				return;
			}
		}
	} else if ((nline = onscreen(pos)) >= 0)
	{
		/*
		 * The line is currently displayed.  
		 * Just scroll there.
		 */
		forw(nline, position(BOTTOM_PLUS_ONE), 1, 0);
		return;
	}

	/*
	 * Line is not on screen.
	 * Back up to the beginning of the current line.
	 */
	if (ch_seek(pos))
	{
		error("Cannot seek to that position");
		return;
	}
	while ((c = ch_back_get()) != '\n' && c != EOF)
		;
	if (c == '\n')
		(void) ch_forw_get();

	/*
	 * Clear and paint the screen.
	 */
	prepaint(ch_tell());
}

/*
 * The table of marks.
 * A mark is simply a position in the file.
 */
static POSITION marks[26];

/*
 * Initialize the mark table to show no marks are set.
 */
	public void
init_mark()
{
	int i;

	for (i = 0;  i < 26;  i++)
		marks[i] = NULL_POSITION;
}

/*
 * See if a mark letter is valid (between a and z).
 */
	static int
badmark(c)
	int c;
{
	if (c < 'a' || c > 'z')
	{
		error("Choose a letter between 'a' and 'z'");
		return (1);
	}
	return (0);
}

/*
 * Set a mark.
 */
	public void
setmark(c)
	int c;
{
	if (badmark(c))
		return;
	marks[c-'a'] = position(TOP);
}

/*
 * Go to a previously set mark.
 */
	public void
gomark(c)
	int c;
{
	POSITION pos;

	if (badmark(c))
		return;
	if ((pos = marks[c-'a']) == NULL_POSITION)
		error("mark not set");
	else
		jump_loc(pos);
}

/*
 * Search for the n-th occurence of a specified pattern, 
 * either forward (direction == '/'), or backwards (direction == '?').
 */
	public void
search(direction, pattern, n)
	int direction;
	char *pattern;
	register int n;
{
	register int search_forward = (direction == '/');
	POSITION pos, linepos;

#if RECOMP
	char *re_comp();
	char *errmsg;

	/*
	 * (re_comp handles a null pattern internally, 
	 *  so there is no need to check for a null pattern here.)
	 */
	if ((errmsg = re_comp(pattern)) != NULL)
	{
		error(errmsg);
		return;
	}
#else
#if REGCMP
	char *regcmp();
	static char *cpattern = NULL;

	if (pattern == NULL || *pattern == '\0')
	{
		/*
		 * A null pattern means use the previous pattern.
		 * The compiled previous pattern is in cpattern, so just use it.
		 */
		if (cpattern == NULL)
		{
			error("No previous regular expression");
			return;
		}
	} else
	{
		/*
		 * Otherwise compile the given pattern.
		 */
		char *s;
		if ((s = regcmp(pattern, 0)) == NULL)
		{
			error("Invalid pattern");
			return;
		}
		if (cpattern != NULL)
			free(cpattern);
		cpattern = s;
	}
#else
	static char lpbuf[100];
	static char *last_pattern = NULL;

	if (pattern == NULL || *pattern == '\0')
	{
		/*
		 * Null pattern means use the previous pattern.
		 */
		if (last_pattern == NULL)
		{
			error("No previous regular expression");
			return;
		}
		pattern = last_pattern;
	} else
	{
		strcpy(lpbuf, pattern);
		last_pattern = lpbuf;
	}
#endif
#endif

	/*
	 * Figure out where to start the search.
	 */

	if (position(TOP) == NULL_POSITION)
	{
		/*
		 * Nothing is currently displayed.
		 * Start at the beginning of the file.
		 * (This case is mainly for first_cmd searches,
		 * for example, "+/xyz" on the command line.)
		 */
		pos = (POSITION)0;
	} else if (!search_forward)
	{
		/*
		 * Backward search: start just before the top line
		 * displayed on the screen.
		 */
		pos = position(TOP);
	} else if (top_search)
	{
		/*
		 * Forward search and "start from top".
		 * Start at the second line displayed on the screen.
		 */
		pos = position(TOP_PLUS_ONE);
	} else
	{
		/*
		 * Forward search but don't "start from top".
		 * Start just after the bottom line displayed on the screen.
		 */
		pos = position(BOTTOM_PLUS_ONE);
	}

	if (pos == NULL_POSITION)
	{
		/*
		 * Can't find anyplace to start searching from.
		 */
		error("Nothing to search");
		return;
	}

	for (;;)
	{
		/*
		 * Get lines until we find a matching one or 
		 * until we hit end-of-file (or beginning-of-file 
		 * if we're going backwards).
		 */
		if (sigs)
			/*
			 * A signal aborts the search.
			 */
			return;

		if (search_forward)
		{
			/*
			 * Read the next line, and save the 
			 * starting position of that line in linepos.
			 */
			linepos = pos;
			pos = forw_raw_line(pos);
		} else
		{
			/*
			 * Read the previous line and save the
			 * starting position of that line in linepos.
			 */
			pos = back_raw_line(pos);
			linepos = pos;
		}

		if (pos == NULL_POSITION)
		{
			/*
			 * We hit EOF/BOF without a match.
			 */
			error("Pattern not found");
			return;
		}

		/*
		 * Test the next line to see if we have a match.
		 * This is done in a variety of ways, depending
		 * on what pattern matching functions are available.
		 */
#if REGCMP
		if ( (regex(cpattern, line) != NULL)
#else
#if RECOMP
		if ( (re_exec(line) == 1)
#else
		if ( (match(pattern, line))
#endif
#endif
				&& (--n <= 0) )
			/*
			 * Found the matching line.
			 */
			break;
	}
	jump_loc(linepos);
}

#if (!REGCMP) && (!RECOMP)
/*
 * We have neither regcmp() nor re_comp().
 * We use this function to do simple pattern matching.
 * It supports no metacharacters like *, etc.
 */
	static int
match(pattern, buf)
	char *pattern, *buf;
{
	register char *pp, *lp;

	for ( ;  *buf != '\0';  buf++)
	{
		for (pp = pattern, lp = buf;  *pp == *lp;  pp++, lp++)
			if (*pp == '\0' || *lp == '\0')
				break;
		if (*pp == '\0')
			return (1);
	}
	return (0);
}
#endif
SHAR_EOF
fi
if test -f 'prompt.c'
then
	echo shar: "will not over-write existing file 'prompt.c'"
else
cat << \SHAR_EOF > 'prompt.c'
/*
 * Prompting and other messages.
 * There are three flavors of prompts, SHORT, MEDIUM and LONG,
 * selected by the -m/-M options.
 * A prompt is either a colon or a message composed of various
 * pieces, such as the name of the file being viewed, the percentage
 * into the file, etc.
 */

#include "less.h"
#include "position.h"

extern int pr_type;
extern int ispipe;
extern int hit_eof;
extern int new_file;
extern int sc_width;
extern char current_file[];
extern int ac;
extern char **av;
extern int curr_ac;

static char message[500];

/*
 * Append the name of the current file (to the message buffer).
 */
	static void
ap_filename()
{
	if (!ispipe)
		sprintf(message + strlen(message), 
			"%s", current_file);
}

/*
 * Append the "file N of M" message.
 */
	static void
ap_of()
{
	if (ac > 1)
		sprintf(message + strlen(message), 
			" (file %d of %d)", curr_ac+1, ac);
}

/*
 * Append the byte offset into the current file.
 */
	static void
ap_byte()
{
	POSITION pos, len;

	pos = position(BOTTOM_PLUS_ONE);
	if (pos != NULL_POSITION)
	{
		sprintf(message + strlen(message), 
			" byte %ld", pos);
		len = ch_length();
		if (len > 0)
			sprintf(message + strlen(message), 
				"/%ld", len);
	}
}

/*
 * Append the percentage into the current file.
 * If we cannot find the percentage and must_print is true,
 * the use the byte offset.
 */
	static void
ap_percent(must_print)
{
	POSITION pos,len;

	pos = position(BOTTOM_PLUS_ONE);
	len = ch_length();
	if (len > 0 && pos != NULL_POSITION)
		sprintf(message + strlen(message),
			" (%ld%%)", (100 * pos) / len);
	else if (must_print)
		ap_byte();
}

/*
 * Append the end-of-file message.
 */
	static void
ap_eof()
{
	strcat(message, " END");
	if (curr_ac + 1 < ac)
		sprintf(message + strlen(message),
			" - Next: %s", av[curr_ac+1]);
}

/*
 * Return a message suitable for printing by the "=" command.
 */
	public char *
eq_message()
{
	message[0] = '\0';
	ap_filename();
	ap_of();
	ap_byte();
	ap_percent(0);
	/*
	 * Truncate to the screen width.
	 * {{ This isn't very nice. }}
	 */
	message[error_width()] = '\0';
	return (message);
}

/*
 * Return a prompt.
 * This depends on the prompt type (SHORT, MEDIUM, LONG), etc.
 * If we can't come up with an appropriate prompt, return NULL
 * and the caller will prompt with a colon.
 */
	public char *
pr_string()
{
	message[0] = '\0';
	switch (pr_type)
	{
	case PR_SHORT:
		if (new_file)
		{
			ap_filename();
			ap_of();
		}
		if (hit_eof)
			ap_eof();
		break;
	case PR_MEDIUM:
		if (new_file)
		{
			ap_filename();
			ap_of();
		}
		if (hit_eof)
			ap_eof();
		else
			ap_percent(1);
		break;
	case PR_LONG:
		ap_filename();
		if (new_file)
			ap_of();
		ap_byte();
		if (hit_eof)
			ap_eof();
		else
			ap_percent(0);
		break;
	}
	new_file = 0;
	if (message[0] == '\0')
		return (NULL);
	/*
	 * Truncate to the screen width.
	 * {{ This isn't very nice. }}
	 */
	message[sc_width-2] = '\0';
	return (message);
}
SHAR_EOF
fi
if test -f 'screen.c'
then
	echo shar: "will not over-write existing file 'screen.c'"
else
cat << \SHAR_EOF > 'screen.c'
/*
 * Routines which deal with the characteristics of the terminal.
 * Uses termcap to be as terminal-independent as possible.
 *
 * {{ Someday this should be rewritten to use curses. }}
 */

#include "less.h"
#if XENIX
#include <sys/types.h>
#include <sys/ioctl.h>
#endif

#if TERMIO
#include <termio.h>
#else
#include <sgtty.h>
#endif

/*
 * Strings passed to tputs() to do various terminal functions.
 */
static char
	*sc_pad,		/* Pad string */
	*sc_home,		/* Cursor home */
	*sc_addline,		/* Add line, scroll down following lines */
	*sc_lower_left,		/* Cursor to last line, first column */
	*sc_move,		/* General cursor positioning */
	*sc_clear,		/* Clear screen */
	*sc_eol_clear,		/* Clear to end of line */
	*sc_s_in,		/* Enter standout (highlighted) mode */
	*sc_s_out,		/* Exit standout mode */
	*sc_u_in,		/* Enter underline mode */
	*sc_u_out,		/* Exit underline mode */
	*sc_b_in,		/* Enter bold mode */
	*sc_b_out,		/* Exit bold mode */
	*sc_visual_bell,	/* Visual bell (flash screen) sequence */
	*sc_backspace,		/* Backspace cursor */
	*sc_init,		/* Startup terminal initialization */
	*sc_deinit;		/* Exit terminal de-intialization */
static int dumb;
static int hard;

public int auto_wrap;		/* Terminal does \r\n when write past margin */
public int ignaw;		/* Terminal ignores \n immediately after wrap */
public int erase_char, kill_char; /* The user's erase and line-kill chars */
public int sc_width, sc_height;	/* Height & width of screen */
public int sc_window = -1;	/* window size for forward and backward */
public int bo_width, be_width;	/* Printing width of boldface sequences */
public int ul_width, ue_width;	/* Printing width of underline sequences */
public int so_width, se_width;	/* Printing width of standout sequences */

/*
 * These two variables are sometimes defined in,
 * and needed by, the termcap library.
 * It may be necessary on some systems to declare them extern here.
 */
/*extern*/ short ospeed;	/* Terminal output baud rate */
/*extern*/ char PC;		/* Pad character */

extern int quiet;		/* If VERY_QUIET, use visual bell for bell */
extern int know_dumb;		/* Don't complain about a dumb terminal */
extern int back_scroll;
char *tgetstr();
char *tgoto();

/*
 * Change terminal to "raw mode", or restore to "normal" mode.
 * "Raw mode" means 
 *	1. An outstanding read will complete on receipt of a single keystroke.
 *	2. Input is not echoed.  
 *	3. On output, \n is mapped to \r\n.
 *	4. \t is NOT be expanded into spaces.
 *	5. Signal-causing characters such as ctrl-C (interrupt),
 *	   etc. are NOT disabled.
 * It doesn't matter whether an input \n is mapped to \r, or vice versa.
 */
	public void
raw_mode(on)
	int on;
{
#if TERMIO
	struct termio s;
	static struct termio save_term;

	if (on)
	{
		/*
		 * Get terminal modes.
		 */
		ioctl(2, TCGETA, &s);

		/*
		 * Save modes and set certain variables dependent on modes.
		 */
		save_term = s;
		ospeed = s.c_cflag & CBAUD;
		erase_char = s.c_cc[VERASE];
		kill_char = s.c_cc[VKILL];

		/*
		 * Set the modes to the way we want them.
		 */
		s.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL);
		s.c_oflag |=  (OPOST|ONLCR|TAB3);
		s.c_oflag &= ~(OCRNL|ONOCR|ONLRET);
		s.c_cc[VMIN] = 1;
		s.c_cc[VTIME] = 0;
	} else
	{
		/*
		 * Restore saved modes.
		 */
		s = save_term;
	}
	ioctl(2, TCSETAW, &s);
#else
	struct sgttyb s;
	static struct sgttyb save_term;

	if (on)
	{
		/*
		 * Get terminal modes.
		 */
		ioctl(2, TIOCGETP, &s);

		/*
		 * Save modes and set certain variables dependent on modes.
		 */
		save_term = s;
		ospeed = s.sg_ospeed;
		erase_char = s.sg_erase;
		kill_char = s.sg_kill;

		/*
		 * Set the modes to the way we want them.
		 */
		s.sg_flags |= CBREAK;
		s.sg_flags &= ~(ECHO|XTABS);
	} else
	{
		/*
		 * Restore saved modes.
		 */
		s = save_term;
	}
	ioctl(2, TIOCSETN, &s);
#endif
}

static int couldnt = 0;

	static void
cannot(s)
	char *s;
{
	if (know_dumb)
		/* 
		 * He knows he has a dumb terminal, so don't tell him. 
		 */
		return;

	printf("WARNING: terminal cannot \"%s\"\n", s);
	couldnt = 1;
}

/*
 * Get terminal capabilities via termcap.
 */
	public void
get_term()
{
	char termbuf[1024];
	char *sp;
	static char sbuf[150];

	char *getenv();

	/*
	 * Find out what kind of terminal this is.
	 */
	if (tgetent(termbuf, getenv("TERM")) <= 0)
		dumb = 1;

	/*
	 * Get size of the screen.
	 */
	if (dumb || (sc_height = tgetnum("li")) < 0 || tgetflag("hc"))
	{
		/* Oh no, this is a hardcopy terminal. */
		hard = 1;
		sc_height = 24;
	}
	/*
	 * This is terrible - the following if "knows" that it is being
	 * executed *after* command line and environment options have
	 * already been parsed.  Should it be executed in the main program
	 * instead?
	 */
	if ((sc_window <= 0) || (sc_window >= sc_height))
		sc_window = sc_height-1;
	if (dumb || (sc_width = tgetnum("co")) < 0)
		sc_width = 80;

	auto_wrap = tgetflag("am");
	ignaw = tgetflag("xn");

	/*
	 * Assumes termcap variable "sg" is the printing width of
	 * the standout sequence, the end standout sequence,
	 * the underline sequence, the end underline sequence,
	 * the boldface sequence, and the end boldface sequence.
	 */
	if ((so_width = tgetnum("sg")) < 0)
		so_width = 0;
	be_width = bo_width = ue_width = ul_width = se_width = so_width;

	/*
	 * Get various string-valued capabilities.
	 */
	sp = sbuf;

	sc_pad = (dumb) ? NULL : tgetstr("pc", &sp);
	if (sc_pad != NULL)
		PC = *sc_pad;

	sc_init = (dumb) ? NULL : tgetstr("ti", &sp);
	if (sc_init == NULL)
		sc_init = "";

	sc_deinit= (dumb) ? NULL : tgetstr("te", &sp);
	if (sc_deinit == NULL)
		sc_deinit = "";

	sc_eol_clear = (dumb) ? NULL : tgetstr("ce", &sp);
	if (hard || sc_eol_clear == NULL || *sc_eol_clear == '\0')
	{
		cannot("clear to end of line");
		sc_eol_clear = "";
	}

	sc_clear = (dumb) ? NULL : tgetstr("cl", &sp);
	if (hard || sc_clear == NULL || *sc_clear == '\0')
	{
		cannot("clear screen");
		sc_clear = "\n\n";
	}

	sc_move = (dumb) ? NULL : tgetstr("cm", &sp);
	if (hard || sc_move == NULL || *sc_move == '\0')
	{
		/*
		 * This is not an error here, because we don't 
		 * always need sc_move.
		 * We need it only if we don't have home or lower-left.
		 */
		sc_move = "";
	}

	sc_s_in = (dumb) ? NULL : tgetstr("so", &sp);
	if (hard || sc_s_in == NULL)
		sc_s_in = "";

	sc_s_out = (dumb) ? NULL : tgetstr("se", &sp);
	if (hard || sc_s_out == NULL)
		sc_s_out = "";

	sc_u_in = (dumb) ? NULL : tgetstr("us", &sp);
	if (hard || sc_u_in == NULL)
		sc_u_in = sc_s_in;

	sc_u_out = (dumb) ? NULL : tgetstr("ue", &sp);
	if (hard || sc_u_out == NULL)
		sc_u_out = sc_s_out;

	sc_b_in = (dumb) ? NULL : tgetstr("md", &sp);
	if (hard || sc_b_in == NULL)
	{
		sc_b_in = sc_s_in;
		sc_b_out = sc_s_out;
	} else
	{
		sc_b_out = (dumb) ? NULL : tgetstr("me", &sp);
		if (hard || sc_b_out == NULL)
			sc_b_out = "";
	}

	sc_visual_bell = (dumb) ? NULL : tgetstr("vb", &sp);
	if (hard || sc_visual_bell == NULL)
		sc_visual_bell = "";

	sc_home = (dumb) ? NULL : tgetstr("ho", &sp);
	if (hard || sc_home == NULL || *sc_home == '\0')
	{
		if (*sc_move == '\0')
		{
			cannot("home cursor");
			/*
			 * This last resort for sc_home is supposed to
			 * be an up-arrow suggesting moving to the 
			 * top of the "virtual screen". (The one in
			 * your imagination as you try to use this on
			 * a hard copy terminal.)
			 */
			sc_home = "|\b^";		
		} else
		{
			/* 
			 * No "home" string,
			 * but we can use "move(0,0)".
			 */
			strcpy(sp, tgoto(sc_move, 0, 0));
			sc_home = sp;
			sp += strlen(sp) + 1;
		}
	}

	sc_lower_left = (dumb) ? NULL : tgetstr("ll", &sp);
	if (hard || sc_lower_left == NULL || *sc_lower_left == '\0')
	{
		if (*sc_move == '\0')
		{
			cannot("move cursor to lower left of screen");
			sc_lower_left = "\r";
		} else
		{
			/*
			 * No "lower-left" string, 
			 * but we can use "move(0,last-line)".
			 */
			strcpy(sp, tgoto(sc_move, 0, sc_height-1));
			sc_lower_left = sp;
			sp += strlen(sp) + 1;
		}
	}

	/*
	 * To add a line at top of screen and scroll the display down,
	 * we use "al" (add line) or "sr" (scroll reverse).
	 */
	if (dumb)
		sc_addline = NULL;
	else if ((sc_addline = tgetstr("al", &sp)) == NULL || 
		 *sc_addline == '\0')
		sc_addline = tgetstr("sr", &sp);

	if (hard || sc_addline == NULL || *sc_addline == '\0')
	{
		cannot("scroll backwards");
		sc_addline = "";
		/* Force repaint on any backward movement */
		back_scroll = 0;
	}

	if (dumb || tgetflag("bs"))
		sc_backspace = "\b";
	else
	{
		sc_backspace = tgetstr("bc", &sp);
		if (sc_backspace == NULL || *sc_backspace == '\0')
			sc_backspace = "\b";
	}

	if (couldnt)
		/* Give him time to read all the "cannot" messages. */
		error("");
}


/*
 * Below are the functions which perform all the 
 * terminal-specific screen manipulation.
 */


/*
 * Initialize terminal
 */
	public void
init()
{
	tputs(sc_init, sc_height, putc);
}

/*
 * Deinitialize terminal
 */
	public void
deinit()
{
	tputs(sc_deinit, sc_height, putc);
}

/*
 * Home cursor (move to upper left corner of screen).
 */
	public void
home()
{
	tputs(sc_home, 1, putc);
}

/*
 * Add a blank line (called with cursor at home).
 * Should scroll the display down.
 */
	public void
add_line()
{
	tputs(sc_addline, sc_height, putc);
}

/*
 * Move cursor to lower left corner of screen.
 */
	public void
lower_left()
{
	tputs(sc_lower_left, 1, putc);
}

/*
 * Ring the terminal bell.
 */
	public void
bell()
{
	if (quiet == VERY_QUIET)
		vbell();
	else
		putc('\7');
}

/*
 * Output the "visual bell", if there is one.
 */
	public void
vbell()
{
	if (*sc_visual_bell == '\0')
		return;
	tputs(sc_visual_bell, sc_height, putc);
}

/*
 * Clear the screen.
 */
	public void
clear()
{
	tputs(sc_clear, sc_height, putc);
}

/*
 * Clear from the cursor to the end of the cursor's line.
 * {{ This must not move the cursor. }}
 */
	public void
clear_eol()
{
	tputs(sc_eol_clear, 1, putc);
}

/*
 * Begin "standout"
 */
	public void
so_enter()
{
	tputs(sc_s_in, 1, putc);
}

/*
 * End "standout".
 */
	public void
so_exit()
{
	tputs(sc_s_out, 1, putc);
}

/*
 * Begin "underline" (hopefully real underlining, 
 * otherwise whatever the terminal provides).
 */
	public void
ul_enter()
{
	tputs(sc_u_in, 1, putc);
}

/*
 * End "underline".
 */
	public void
ul_exit()
{
	tputs(sc_u_out, 1, putc);
}

/*
 * Begin "bold"
 */
	public void
bo_enter()
{
	tputs(sc_b_in, 1, putc);
}

/*
 * End "bold".
 */
	public void
bo_exit()
{
	tputs(sc_b_out, 1, putc);
}

/*
 * Erase the character to the left of the cursor 
 * and move the cursor left.
 */
	public void
backspace()
{
	/* 
	 * Try to erase the previous character by overstriking with a space.
	 */
	tputs(sc_backspace, 1, putc);
	putc(' ');
	tputs(sc_backspace, 1, putc);
}

/*
 * Output a plain backspace, without erasing the previous char.
 */
	public void
putbs()
{
	tputs(sc_backspace, 1, putc);
}
SHAR_EOF
fi
if test -f 'signal.c'
then
	echo shar: "will not over-write existing file 'signal.c'"
else
cat << \SHAR_EOF > 'signal.c'
/*
 * Routines dealing with signals.
 *
 * A signal usually merely causes a bit to be set in the "signals" word.
 * At some convenient time, the mainline code checks to see if any
 * signals need processing by calling psignal().
 * An exception is made if we are reading from the keyboard when the
 * signal is received.  Some operating systems will simply call the
 * signal handler and NOT return from the read (with EINTR).
 * To handle this case, we service the interrupt directly from
 * the handler if we are reading from the keyboard.
 */

#include "less.h"
#include <signal.h>
#include <setjmp.h>

/*
 * The type of signal handler functions.
 * Usually int, although it should be void.
 */
typedef	int		HANDLER;

/*
 * "sigs" contains bits indicating signals which need to be processed.
 */
public int sigs;
#define	S_INTERRUPT	01
#ifdef SIGTSTP
#define	S_STOP		02
#endif

extern int reading;
extern char *first_cmd;
extern jmp_buf main_loop;

/*
 * Interrupt signal handler.
 */
	static HANDLER
interrupt()
{
	SIGNAL(SIGINT, interrupt);
	sigs |= S_INTERRUPT;
	if (reading)
		psignals();
}

#ifdef SIGTSTP
/*
 * "Stop" (^Z) signal handler.
 */
	static HANDLER
stop()
{
	SIGNAL(SIGTSTP, stop);
	sigs |= S_STOP;
	if (reading)
		psignals();
}
#endif

/*
 * Set up the signal handlers.
 */
	public void
init_signals()
{
	(void) SIGNAL(SIGINT, interrupt);
#ifdef SIGTSTP
	(void) SIGNAL(SIGTSTP, stop);
#endif
}

/*
 * Process any signals we have recieved.
 * A received signal cause a bit to be set in "sigs".
 */
	public void 
psignals()
{
	register int tsignals;

	tsignals = sigs;
	sigs = 0;
	if (tsignals == 0)
		return;

	dropout();		/* Discard any buffered output */

#ifdef SIGTSTP
	if (tsignals & S_STOP)
	{
		/*
		 * Clean up the terminal.
		 */
#ifdef SIGTTOU
		SIGNAL(SIGTTOU, SIG_IGN);
#endif
		lower_left();
		clear_eol();
		flush();
		raw_mode(0);
#ifdef SIGTTOU
		SIGNAL(SIGTTOU, SIG_DFL);
#endif
		SIGNAL(SIGTSTP, SIG_DFL);
#if SIGSETMASK
		/*
		 * This system will not allow us to send a 
		 * stop signal (SIGTSTP) to ourself
		 * while we are in the signal handler, like maybe now.
		 * (This can be the case if we are reading; see comment above.)
		 * So we ask the silly system for permission to do so.
		 */
		sigsetmask(0);
#endif
		kill(getpid(), SIGTSTP);
		/*
		 * ... Bye bye. ...
		 * Hopefully we'll be back later and resume here...
		 * Reset the terminal and arrange to repaint the
		 * screen when we get back to the main command loop.
		 */
		SIGNAL(SIGTSTP, stop);
		raw_mode(1);
		first_cmd = "r";
		longjmp(main_loop, 1);
	}
#endif
	if (tsignals & S_INTERRUPT)
	{
		bell();
		/*
		 * {{ You may wish to replace the bell() with 
		 *    error("Interrupt"); }}
		 */
	}

	longjmp(main_loop, 1);
}

/*
 * Pass the specified command to a shell to be executed.
 * Like plain "system()", but handles resetting terminal modes, etc.
 */
	public void
lsystem(cmd)
	char *cmd;
{
	int inp;

	/*
	 * Print the command which is to be executed.
	 */
	lower_left();
	clear_eol();
	puts("!");
	puts(cmd);
	puts("\n");

	/*
	 * De-initialize the terminal and take out of raw mode.
	 */
	deinit();
	flush();
	raw_mode(0);

	/*
	 * Restore signals to their defaults.
	 */
	SIGNAL(SIGINT, SIG_DFL);
#ifdef SIGTSTP
	SIGNAL(SIGTSTP, SIG_DFL);
#endif
	/*
	 * Pass the command to the system to be executed.
	 */
	inp = dup(0);
	close(0);
	open("/dev/tty", 0);

	system(cmd);

	close(0);
	dup(inp);
	close(inp);

	/*
	 * Reset signals, raw mode, etc.
	 */
	init_signals();
	raw_mode(1);
	init();
}
SHAR_EOF
fi
if test -f 'ttyin.c'
then
	echo shar: "will not over-write existing file 'ttyin.c'"
else
cat << \SHAR_EOF > 'ttyin.c'
/*
 * Routines dealing with getting input from the keyboard (i.e. from the user).
 */

#include "less.h"

/*
 * The boolean "reading" is set true or false according to whether
 * we are currently reading from the keyboard.
 * This information is used by the signal handling stuff in signal.c.
 * {{ There are probably some race conditions here
 *    involving the variable "reading". }}
 */
public int reading;

static int tty;

/*
 * Open keyboard for input.
 * (Just use file descriptor 2.)
 */
	public void
open_getc()
{
	tty = 2;
}

/*
 * Get a character from the keyboard.
 */
	public int
getc()
{
	char c;
	int result;

	reading = 1;
	do
	{
		flush();
		result = read(tty, &c, 1);
	} while (result != 1);
	reading = 0;
	return (c & 0177);
}
SHAR_EOF
fi
if test -f 'version.c'
then
	echo shar: "will not over-write existing file 'version.c'"
else
cat << \SHAR_EOF > 'version.c'
/*
 *		less
 *	Copyright (c) 1984,1985  Mark Nudelman
 *
 *	This program may be freely used and/or modified, 
 *	with the following provisions:
 *	1. This notice and the above copyright notice must remain intact.
 *	2. Neither this program, nor any modification of it,
 *	   may not be sold for profit without written consent of the author.
 *
 *	-----------------------------------------------------------------
 *
 *	This program is a paginator similar to "more", 
 *	but allows you to move both forward and backward in the file.  
 *	Commands are based on "more" and "vi".
 *
 *	----------------------- CHANGES ---------------------------------
 *
 *	    Allowed use on standard input		1/29/84   markn
 *	    Added E, N, P commands			2/1/84    markn
 *	    Added '=' command, 'stop' signal handling	4/17/84   markn
 *	    Added line folding				4/20/84   markn
 *	v2: Fixed '=' command to use BOTTOM_PLUS_ONE, 
 *	    instead of TOP, added 'p' & 'v' commands	4/27/84   markn
 *	v3: Added -m and -t options, '-' command	5/3/84    markn
 *	v4: Added LESS environment variable		5/3/84    markn
 *	v5: New comments, fixed '-' command slightly	5/3/84    markn
 *	v6: Added -Q, visual bell			5/15/84   markn
 *	v7: Fixed jump_back(n) bug: n should count real
 *	    lines, not folded lines.  Also allow number
 *	    on G command.				5/24/84   markn
 *	v8: Re-do -q and -Q commands			5/30/84   markn
 *	v9: Added "+<cmd>" argument			9/25/84   markn
 *	v10: Fixed bug in -b<n> argument processing	10/10/84  markn
 *	v11: Made error() ring bell if \n not entered.	10/18/84  markn
 *	-----------------------------------------------------------------
 *	v12: Reorganized signal handling and made
 *	     portable to 4.2bsd.			2/13/85   mark
 *	v13: Reword error message for '-' command.	2/16/85   mark
 *	v14: Added -bf and -bp variants of -b.		2/22/85   mark
 *	v15: Miscellaneous changes.			2/25/85   mark
 *	v16: Added -u flag for backspace processing.	3/13/85   mark
 *	v17: Added j and k commands, 
 *		changed -t default.			4/13/85   mark
 *	v18: Rewrote signal handling code.		4/20/85   mark
 *	v19: Got rid of "verbose" eq_message().		5/2/85    mark
 *	     Made search() scroll in some cases.
 *	v20: Fixed screen.c ioctls for System V.	5/21/85   mark
 *	v21: Fixed some first_cmd bugs.			5/23/85   mark
 *	v22: Added support for no RECOMP nor REGCMP.	5/24/85   mark
 *	v23: Miscellanous changes and prettying up.	5/25/85   mark
 *      v24: Added ti,te terminal init & de-init       6/3/85 Mike Kersenbrock
 *	v25: Added -U flag, standout mode underlining.	6/8/85    mark
 *	v26: Added -M flag.				6/9/85    mark
 *	     Use underline termcap (us) if it exists.
 *	v27: Renamed some variables to make unique in	6/15/85   mark
 *	     6 chars.  Minor fix to -m.
 *	v28: Fixed right margin bug.			6/28/85   mark
 *	v29: Incorporated M.Rose's changes to signal.c	6/28/85   mark
 *	v30: Fixed stupid bug in argument processing.	6/29/85   mark
 *	v31: Added -p flag, changed repaint algorithm.  7/15/85   mark
 *	     Added kludge for magic cookie terminals.
 *	v32: Added cat_file if output not a tty.	7/16/85   mark
 *	v33: Added -e flag and EDITOR.			7/23/85   mark
 *	v34: Added -s flag.				7/26/85   mark
 *	v35: Rewrote option handling; added option.c.	7/27/85   mark
 *	v36: Fixed -e flag to work if not last file.	7/29/85   mark
 *	v37: Added -x flag.				8/10/85   mark
 *	v38: Changed prompting; created prompt.c.	8/19/85   mark
 *	v39: (Not -p) does not initially clear screen.	8/24/85   mark
 *	v40: Added "skipping" indicator in forw().	8/26/85   mark
 *	v41: ONLY_RETURN, control char commands,	9/17/85   mark
 *	     faster search, other minor fixes.
 *	v42: Added ++ command line syntax;		9/25/85   mark
 *	     ch_fsize for pipes.
 *	v43: Added -h flag, changed prim.c algorithms.	10/15/85  mark
 *	v44: Made END print in all cases of eof;	10/16/85  mark
 *	     ignore SIGTTOU after receiving SIGTSTP.
 *	v45: Never print backspaces unless -u.		10/16/85  mark
 *	v46: Backwards scroll in jump_loc.		10/24/85  mark
 *	v47: Fixed bug in edit(): *first_cmd==0		10/30/85  mark
 *	v48: Use TIOCSETN instead of TIOCSETP.		11/16/85  mark
 *	     Added marks (m and ' commands).
 *	-----------------------------------------------------------------
 */

char version[] = "@(#) less  version 48";
SHAR_EOF
fi
exit 0
#	End of shell archive