From:	CRDGW2::CRDGW2::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX"  1-MAY-1989 18:29
To:	MRGATE::"ARISIA::EVERHART"
Subj:	Yet another MORE posting.  Part 1/2.

Received: From KL.SRI.COM by CRVAX.SRI.COM with TCP; Sun, 30 APR 89 20:41:42 PDT
Received: from ucbvax.Berkeley.EDU by KL.SRI.COM with TCP; Sun, 30 Apr 89 20:29:23 PDT
Received: by ucbvax.Berkeley.EDU (5.61/1.36)
	id AA27642; Sun, 30 Apr 89 20:17:44 -0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews
	for info-vax@kl.sri.com (info-vax@kl.sri.com)
	(contact usenet@ucbvax.Berkeley.EDU if you have questions)
Date: 1 May 89 02:09:56 GMT
From: unmvax!nmtsun!warner%hydrovax.nmt.edu@ucbvax.Berkeley.EDU  (M. Warner Losh)
Organization: New Mexico Tech Hydrology Program
Subject: Yet another MORE posting.  Part 1/2.
Message-Id: <2518@nmtsun.nmt.edu>
Sender: info-vax-request@kl.sri.com
To: info-vax@kl.sri.com


I've gotten a lot of requests for the MORE program that I said that I
had.  So here it is.  I've wrapped it in VMS_SHARE format, so that stuff
doesn't get munched accross gateways and stuff.  This is the last MORE
distribution that I will do from NMT.  I'm graduating in May and don't
quite know where I'll land just yet.

The main improvement of this MORE over the other that was posted a few
days ago is that it understand some, but not quite all, of the unix
file names.  It understands everything that I know of in a unix file
name excpet for:
	/dev/*		(Not all that useful)
	./x		(Ditto, why not say x or []x)
	~user		(don't know how to do on VMS w/o privs)
	/file		(Didn't think of it until just now)

However the following do seem to work:
	~/xxx
	../xx
	../../../xx/yy
	name/dr2
	/dir1/dir2/dir3/file

Have fun with it.  If you really like it, let me know.  If you make changes
to it, please forward them back to me at warner@hydrovax.nmt.edu.  It should
be good for at least 6 months.

This is the first of two parts.
$! ................... Cut between dotted lines and save. ...................
$!...........................................................................
$! VAX/VMS archive file created by VMS_SHARE V06.10 7-FEB-1989.
$!
$! VMS_SHARE was written by James Gray (Gray:OSBUSouth@Xerox.COM) from
$! VMS_SHAR by Michael Bednarek (U3369429@ucsvc.dn.mu.oz.au).
$!
$! To unpack, simply save, concatinate all parts into one file and
$! execute (@) that file.
$!
$! This archive was created by user WARNER
$! on 30-APR-1989 20:16:03.08.
$!
$! ATTENTION: To keep each article below 31 blocks (15872 bytes), this
$!            program has been transmitted in 2 parts.  You should
$!            concatenate ALL parts to ONE file and execute (@) that file.
$!
$! It contains the following 1 file:
$!        MORE.C
$!
$!============================================================================
$ SET SYMBOL/SCOPE=( NOLOCAL, NOGLOBAL )
$ VERSION = F$GETSYI( "VERSION" )
$ IF VERSION .GES "V4.4" THEN GOTO VERSION_OK
$ WRITE SYS$OUTPUT "You are running VMS ''VERSION'; ", -
    "VMS_SHARE V06.10 7-FEB-1989 requires VMS V4.4 or higher."
$ EXIT 44 ! SS$_ABORT
$VERSION_OK:
$ GOTO START
$!
$UNPACK_FILE:
$ WRITE SYS$OUTPUT "Creating ''FILE_IS'"
$ DEFINE/USER_MODE SYS$OUTPUT NL:
$ EDIT/TPU/COMMAND=SYS$INPUT/NODISPLAY/OUTPUT='FILE_IS'/NOSECTION -
    VMS_SHARE_DUMMY.DUMMY
b_part := CREATE_BUFFER( "{Part}", GET_INFO( COMMAND_LINE, "file_name" ) )
; s_file_spec := GET_INFO( COMMAND_LINE, "output_file" ); SET( OUTPUT_FILE
, b_part, s_file_spec ); b_errors := CREATE_BUFFER( "{Errors}" ); i_errors 
:= 0; pat_beg_1 := ANCHOR & "-+-+-+ Beginning"; pat_beg_2 := LINE_BEGIN 
& "+-+-+-+ Beginning"; pat_end := ANCHOR & "+-+-+-+-+ End"; POSITION
( BEGINNING_OF( b_part ) ); LOOP EXITIF SEARCH( SPAN( ' ' )@r_trail 
& LINE_END, FORWARD) = 0; POSITION( r_trail ); ERASE( r_trail ); ENDLOOP
; POSITION( BEGINNING_OF( b_part ) ); i_append_line := 0; LOOP EXITIF MARK
( NONE ) = END_OF( b_part ); s_x := ERASE_CHARACTER( 1 )
; IF s_x = '+' THEN r_skip := SEARCH( pat_beg_1, FORWARD, EXACT ); IF r_skip 
<> 0 THEN s_x := ''; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ERASE_LINE; ENDIF
; ENDIF; IF s_x = '-' THEN r_skip := SEARCH( pat_end, FORWARD, EXACT )
; IF r_skip <> 0 THEN s_x := ''; MOVE_HORIZONTAL( -CURRENT_OFFSET ); m_skip 
:= MARK( NONE ); r_skip := SEARCH( pat_beg_2, FORWARD, EXACT ); IF r_skip 
<> 0 THEN POSITION( END_OF( r_skip ) ); MOVE_HORIZONTAL( -CURRENT_OFFSET )
; MOVE_VERTICAL( 1 ); MOVE_HORIZONTAL( -1 ); ELSE POSITION( END_OF( b_part 
) ); ENDIF; ERASE( CREATE_RANGE( m_skip, MARK( NONE ), NONE ) ); ENDIF; ENDIF
; IF s_x = 'V' THEN s_x := ''; IF i_append_line <> 0 THEN APPEND_LINE
; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ENDIF; i_append_line := 1
; MOVE_VERTICAL( 1 ); ENDIF; IF s_x = 'X' THEN s_x := ''; IF i_append_line 
<> 0 THEN APPEND_LINE; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ENDIF
; i_append_line := 0; MOVE_VERTICAL( 1 ); ENDIF; IF s_x <> '' THEN i_errors 
:= i_errors + 1; s_text := CURRENT_LINE; POSITION( b_errors ); COPY_TEXT
( "The following line could not be unpacked properly:" ); SPLIT_LINE
; COPY_TEXT( s_x ); COPY_TEXT( s_text ); POSITION( b_part ); MOVE_VERTICAL
( 1 ); ENDIF; ENDLOOP; POSITION( BEGINNING_OF( b_part ) ); LOOP r_x := SEARCH
( "`", FORWARD, EXACT ); EXITIF r_x = 0; POSITION( r_x ); ERASE_CHARACTER
( 1 ); COPY_TEXT( ASCII( INT( ERASE_CHARACTER( 3 ) ) ) ); ENDLOOP
; IF i_errors = 0 THEN SET( NO_WRITE, b_errors, ON ); ELSE POSITION
( BEGINNING_OF( b_errors ) ); COPY_TEXT( FAO
( "The following !UL errors were detected while unpacking !AS", i_errors
, s_file_spec ) ); SPLIT_LINE; SET( OUTPUT_FILE, b_errors, "SYS$COMMAND" )
; ENDIF; EXIT; 
$ DELETE VMS_SHARE_DUMMY.DUMMY;*
$ CHECKSUM 'FILE_IS
$ WRITE SYS$OUTPUT " CHECKSUM ", -
  F$ELEMENT( CHECKSUM_IS .EQ. CHECKSUM$CHECKSUM, ",", "failed!!,passed." )
$ RETURN
$!
$START: 
$ FILE_IS = "MORE.C"
$ CHECKSUM_IS = 1366469437
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
X  `032
X   A simple MORE/LESS-like program for VMS.
X  `032
X   Shan Xuning, Dept. of Chem. Engr, JHU   18/11/87
X  `032
X   Modified by Robert Drabek
X   Computer Science Department
X   University of Arizona, Tucson
X  `032
X   December 1987:
X   Added wild-card file searching.
X   Added screen routines using SMG.
X   Added raw key input.
X   Fixed window counting.
X   Fixed string search.
X   Fixed a multitude of other bugs and styled it up a bit.
X   Made it more like the Unix version.
X   Added #, N, and D commands.
X  `032
X   Modified by M. Warner Losh
X   System Manager HydroVAX
X   New Mexico Tech, Socorro NM.
X   ...!lanl!unm-la!unmvax!warner%hydrovax
X  `032
X   December 1987
X  `032
X   Fixed both t and b commands so that when they are at the top of the
X   file, they don't do anything
X   Fixed the spawn command so that it only spawns one job, instead of
X   spawning a spawn.
X   If no files are found, then it says no files were found.
X  `032
X   July 1988
X  `032
X   Mapped control characters to '.'
X   Fix the long line problem.
X  `032
X   April 1989
X
X   Slight reformatting of routines I've worked on.
X   Merge changes posted to the net to make this program work on VMS 5.0.
X   Make program compile under VAXC 2.2 on VMS 4.5.  UNIXIO doesn't
X       appear to be around.  I had to define stat_t to get it to work.
X   Add some code to emulate some common UNIX file names.
X   Repost to the net with fixes.  This is the last release of more
X       from WARNER@HYDROVAX.NMT.EDU since I'm graduating in May.  Others
X       fixes from me may follow, but not from nmt.  Only those changes that
X       were documented have been included.  If I missed one, let me know and
X       I'll update my copy and redistribute.
X
X   Modified by Aaron Leonard
X        System Manager UACCIT VAXcluster
X`009University of Arizona
X`009leonard@rvax.ccit.arizona.edu
X
X   July 1988
X  `032
X   Unsupported use of fseek() and ftell() uin module MORE broke with VMS
X   V5.0 VAXC Run-Time Library.  Fixed by replaceing with call to
X   fstat().  Also refrained from exiting on FALSE status retunred from
X   Terminal_Open, so as to work on UNKNOWN type terminals.
X
X   Modified by Jan Trumbo
X        University of Arizona system programmer
X`009trumbo@rvax.ccit.arizona.edu
X
X   November 1988
X
X   Retrain from exiting if search string not found.
X
X   Commands (and their alternates):
X   <SPACE> ==> print next screen (f)
X   <CR>    ==> print next line (e, j, +)
X   s       ==> skip over next screen
X   t       ==> top of the file (g)
X   b       ==> skip backward
X   h       ==> help message (?)
X   #       ==> go to next file (if more than one specified)
X   q       ==> quit
X   !       ==> spawn subprocess
X   /string ==> search forward for string.  The search is case
X   sensitive
X   n       ==> next occurrence of last search string
X  `032
X   Compile using  CC MORE
X   LINK MORE
X   Create a "foreign command" with
X   $ MORE :== $mydisk:[mydir]MORE.EXE
X   where  mydisk  and  mydir  are the names of your disk drive and
X   directory where MORE.EXE will reside.  Use SHOW DEFAULT if you
X   don't know what they are.
X  `032
X   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
X
X#include stdio
X#include ctype
X#include descrip
X#include stat
X
Xtypedef struct stat stat_t;
Xtypedef char bool;
X#define TRUE  1
X#define FALSE 0
X
X#define EOS '\0'
X
X#define MAXNAME    256
X#define MAXWINDOWS 200
X#define MAXFILES   200
X
X#define lower(c) (isupper(c) ? tolower(c) : c)
X
Xbool Terminal_Open();
Xvoid ClrEOL();
Xvoid Ding();
Xvoid standend();
Xvoid standout();
Xint  getkey();
Xchar *convert_unix_to_vms();
X
Xchar *strchr();
Xchar *malloc();
Xchar *strrchr();
X
Xvoid more();
Xbool prwindow();
Xbool prline();
X
Xvoid fix_string();
Xint str_lines();
X
Xint  Screen_Height = 24; /* may be changed below */
Xint  Screen_Width  = 80;
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X`123
X`009int i, j;
X`009char *pn;
X`009FILE *fp;
X`009int nargc; char *nargv[MAXFILES + 1];
X`009bool file_found;
X`009
X`009/* next few lines to deal with lib$find_file() */
X`009static char name[MAXNAME];
X`009struct dsc$descriptor_s name_desc;
X`009struct dsc$descriptor_s result =
X`009`123MAXNAME, DSC$K_DTYPE_T, DSC$K_CLASS_S, name`125;
X`009long context;
X`009
X`009Terminal_Open();
X`009
X`009for (i = 1, nargc = 0; i < argc && nargc <= MAXFILES; i++)
X`009`123
X`009`009context = 0;
X
X`009`009if (strchr (argv[i], '/') != (char *) NULL)
X`009`009`123
X`009`009`009argv[i] = convert_unix_to_vms (argv[i]);
X`009`009`125
X
X`009`009name_desc.dsc$w_length = strlen(argv[i]);
X`009`009name_desc.dsc$b_dtype = DSC$K_DTYPE_T;
X`009`009name_desc.dsc$b_class = DSC$K_CLASS_S;
X`009`009name_desc.dsc$a_pointer = argv[i];
X
X`009`009file_found = FALSE;
X`009`009while (lib$find_file(&name_desc, &result, &context) & 1)
X`009`009`123
X`009`009`009file_found = TRUE;
X`009`009`009if (nargc >= MAXFILES)
X`009`009`009`123
X`009`009`009`009fprintf(stderr, "Only %d files will be read\n",
X`009`009`009`009`009MAXFILES);
X`009`009`009`009break;
X`009`009`009`125
X`009`009`009nargv[++nargc] = malloc((unsigned)strlen(name) + 1);
X`009`009`009strcpy(nargv[nargc], name);
X`009`009`125
X`009`009if (!file_found)
X`009`009`009fprintf (stderr, "Couldn't find file %s\n", argv[i]);
X`009`009lib$find_file_end(&context);
X`009`125
X`009
X`009for (i = 1; i <= nargc; i++)
X`009`123
X`009`009for (j = 0; nargv[i][j] != EOS; j++)
X`009`009`009if (isupper(nargv[i][j]))
X`009`009`009`009nargv[i][j] = tolower(nargv[i][j]);
X`009`009`009else if (nargv[i][j] == ' ')
X`009`009`009`009nargv[i][j] = EOS;
X`009`009if ((fp = fopen(nargv[i], "r")) == NULL)
X`009`009`123
X`009`009`009perror(nargv[i]);
X`009`009`009continue;
X`009`009`125
X`009`009for (pn = nargv[i]; *pn != EOS && *pn != ']'; pn++)
X`009`009`009;
X`009`009if (*pn == ']') pn++;
X`009`009more(fp, pn, i == nargc);
X`009`009fclose(fp);
X`009`125
X`009
X`125  /* main */
X
Xvoid more(fp, fname, last_file)
XFILE *fp;
Xchar *fname;
Xbool  last_file;
X`123
X`009char pattern[BUFSIZ], a_line[BUFSIZ];
X`009int  i, ch, wc, wc_save, line_count, pat_found;
X`009long win[MAXWINDOWS], file_size;
X`009stat_t status_block;
X`009long ftell();
X`009int  find(), fseek();
X`009
X`009win[0] = 0;
X`009fstat (fileno (fp), &status_block);
X`009file_size = status_block.st_size;
X`009
X`009if (!prwindow(fp, Screen_Height - 1, Screen_Width, last_file))
X`009`009return; /* window #0 */  `032
X`009wc = 0;
X`009for (;;)
X`009`123
X`009`009standout();
X`009`009printf("\r--More--(%s, %d%%)", fname,
X`009`009       feof(fp) ? 100 : (int)((double)ftell(fp)/
X`009`009`009`009`009      (double)file_size*100.0));
X`009`009standend();
X`009`009ch = getkey();
X`009`009switch ( lower(ch) )
X`009`009`123
X`009`009case '\r':
X`009`009case '+':
X`009`009case 'e':
X`009`009case 'j':
X`009`009`009win[++wc] = ftell(fp);
X`009`009`009if (!prline(fp))
X`009`009`009`009return;
X`009`009`009break;
X`009`009case ' ':
X`009`009case 'f':
X`009`009`009win[++wc] = ftell(fp);
X`009`009`009if (!prwindow(fp, Screen_Height - 2, Screen_Width,
X`009`009`009`009      last_file))
X`009`009`009`009return;
X`009`009`009break;
X`009`009case 'd':
X`009`009`009win[++wc] = ftell(fp);
X`009`009`009if (!prwindow(fp, Screen_Height / 2, Screen_Width,
X`009`009`009`009      last_file))
X`009`009`009`009return;
X`009`009`009break;
X`009`009case 's':
X`009`009`009standout();
X`009`009`009printf("\nSkipping forward %d lines.\n",
X`009`009`009       Screen_Height - 1);
X`009`009`009standend();
X`009`009`009win[++wc] = ftell(fp);
X`009`009`009for (i = 0; i < Screen_Height - 2; i++)
X`009`009`009`123
X`009`009`009`009if (fgets(a_line, BUFSIZ, fp)==NULL)
X`009`009`009`009`123
X`009`009`009`009`009standout();
X`009`009`009`009`009fputs("END OF FILE", stdout);
X`009`009`009`009`009standend();
X`009`009`009`009`009return;
X`009`009`009`009`125
X`009`009`009`125
X`009`009`009win[++wc] = ftell(fp);
X`009`009`009if (!prwindow(fp, Screen_Height - 1, Screen_Width,
X`009`009`009`009      last_file))
X`009`009`009`009return;
X`009`009`009break;
X`009`009case '/':
X`009`009`009putchar('\r');
X`009`009`009ClrEOL();
X`009`009`009putchar('/');
X`009`009`009get_pattern(pattern);
X`009`009case 'n':
X`009`009`009wc_save = wc;
X`009`009`009fgets(a_line, BUFSIZ, fp);
X`009`009`009line_count = 1;
X`009`009`009while ((pat_found=find(pattern, a_line)) < 0)
X`009`009`009`123
X`009`009`009`009if (fgets(a_line, BUFSIZ, fp) == NULL)
X`009`009`009`009`123
X`009`009`009`009`009wc = wc_save;
X`009`009`009`009`009clearerr (fp);
X`009`009`009`009`009fseek(fp, win[wc], 0);
X`009`009`009`009`009standout();
X`009`009`009`009`009fputs("\nPattern not found.\n",
X`009`009`009`009`009      stdout);
X`009`009`009`009`009standend();
X`009`009`009`009`009break;
X`009`009`009`009`125`032
X`009`009`009`009line_count++;
X`009`009`009`009if (line_count > Screen_Height - 1)
X`009`009`009`009`123
X`009`009`009`009`009line_count = 1;
X`009`009`009`009`009win[++wc] = ftell(fp);
X`009`009`009`009`125
X`009`009`009`125
X`009`009`009if (pat_found > -1)
X`009`009`009`123
X`009`009`009`009putchar('\r');
X`009`009`009`009ClrEOL();
X`009`009`009`009fputs(a_line, stdout);
X`009`009`009`009win[++wc] = ftell(fp);
X`009`009`009`125
X`009`009`009if (!prwindow(fp, Screen_Height - 2, Screen_Width,
X`009`009`009`009      last_file))
X`009`009`009`009return;
X`009`009`009break;
X`009`009case 't':
X`009`009case 'g':
X`009`009`009if (wc != 0)
X`009`009`009`123
X`009`009`009`009wc = 0;
X`009`009`009`009fseek(fp, win[wc], 0);
X`009`009`009`009if (!prwindow(fp, Screen_Height - 1,
X`009`009`009`009`009      Screen_Width, last_file))
X`009`009`009`009`009return;
X`009`009`009`125
X`009`009`009break;
X`009`009case 'b':
X`009`009`009if (wc > 0)
X`009`009`009`123
X`009`009`009`009wc--;
X`009`009`009`009fseek(fp, win[wc], 0);
X`009`009`009`009if (!prwindow(fp, Screen_Height - 1,
X`009`009`009`009`009      Screen_Width, last_file))
X`009`009`009`009`009return;
X`009`009`009`125
X`009`009`009break;
X`009`009case 'h':
X`009`009case '?':
X`009`009`009more_help ();
X`009`009`009fseek(fp, win[wc], 0);
X`009`009`009if (!prwindow(fp, Screen_Height - 1, Screen_Width,
X`009`009`009`009      last_file))
X`009`009`009`009return;
X`009`009`009break;
X`009`009case '!':
X`009`009`009spawn();
X`009`009`009fseek(fp, win[wc], 0);
X`009`009`009if (!prwindow(fp, Screen_Height - 1, Screen_Width,
X`009`009`009`009      last_file))
X`009`009`009`009return;
X`009`009`009break;
X`009`009case '#':
X`009`009`009putchar('\n');
X`009`009`009return;
X`009`009case 'q':
X`009`009`009putchar('\n');
X`009`009`009exit();
X`009`009default:
X`009`009`009Ding();
X`009`009`009putchar('\r');
X`009`009`009break;     `032
X`009`009`125
X`009`125`032
X`125  /* more */
X
Xbool prwindow(fp, height, width, last_file)
XFILE *fp;
Xint height;
Xint width;
Xbool last_file;
X`123
X`009int i;
X`009char *fgets(), str[BUFSIZ];
X`009bool got_line = FALSE;
X`009
X`009putchar('\r'); ClrEOL();
X`009for (i = 0; i < height; i++)
-+-+-+-+-+ End of part 1 +-+-+-+-+-
--
Warner Losh
warner@hydrovax.nmt.edu		...!unmvax!nmtsun!hydrovax
What happened to our innocence, did it go out of style?
My spelling and views are my own.  Only the letters have been changed...

