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

Received: From KL.SRI.COM by CRVAX.SRI.COM with TCP; Sun, 30 APR 89 20:41:28 PDT
Received: from ucbvax.Berkeley.EDU by KL.SRI.COM with TCP; Sun, 30 Apr 89 20:29:17 PDT
Received: by ucbvax.Berkeley.EDU (5.61/1.36)
	id AA27657; Sun, 30 Apr 89 20:18:01 -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 03:00:51 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 2/2
Message-Id: <2519@nmtsun.nmt.edu>
Sender: info-vax-request@kl.sri.com
To: info-vax@kl.sri.com


Here is the second part of the MORE program.

+-+-+-+ Beginning of part 2 +-+-+-+
X`009`123
X`009`009if (fgets(str, BUFSIZ, fp) == NULL)
X`009`009`009break;
X`009`009got_line = TRUE;
X`009`009fix_string(str);
X`009`009printf("%s", str);
X`009`009i += str_lines (str, width);
X`009`125
X`009return got_line && !(feof(fp) && last_file);
X`125  /* prwindow */
X
Xbool prline(fp)
XFILE *fp;
X`123
X`009char *fgets(), str[BUFSIZ];
X`009
X`009putchar('\r'); ClrEOL();
X`009if (fgets(str, BUFSIZ, fp) == NULL)
X`009`009return FALSE;
X`009printf("%s", str);
X`009return TRUE;
X`125  /* prline */
X
X/* get_pattern
X     Read pattern to be search for from the user's keyboard.
X*/
Xget_pattern(pat)
Xchar *pat;
X`123
X`009int i = 0;
X`009
X`009while ((pat[i++] = getchar()) != '\n')
X`009`009;
X`009pat[i - 1] = EOS;
X`125  /* get_pattern */
X
X/* find
X     Find starting index of the first string within the second.
X     Return -1 if not there.  Horribly slow!
X*/
Xint find(t, s)
Xchar *t, *s;
X`123
X`009int i, n;
X`009
X`009n = strlen(t);
X`009for (i = 0; s[i] != EOS; i++)
X`009`009if (strncmp(s+i, t, n) == 0)
X`009`009`009return i;
X`009return -1;
X`009
X`125  /* find */
X
Xspawn()
X`123
X`009printf("\nSpawning subprocess ... use EOJ to return.\n");
X`009lib$spawn();
X`125  /* spawn */
X
X
X/*  -------------------------------------------------------------------
X
X    Contains terminal-handling routines using the SMG routines.
X
X    Author: Robert J. Drabek, Curtis Smith
X
X    Date: Winter 1987
X
X    -------------------------------------------------------------------  */
X
X#define NULL_STR (char *)0
X#define BEL_STR  "\07"
X
X/*  These would normally come from iodef.h and ttdef.h  */
X#define IO$_SENSEMODE 0x27    /* Sense mode of terminal */
X#define TT$_UNKNOWN 0x00    /* Unknown terminal   */
X
X/* Local routines. */
Xstatic void  vmsgtty();
Xstatic char *tgetstr();
Xstatic void  tputs();
Xstatic void  tputone();
X
X/* -------------------------------------------------------------------- */
Xstatic char  *CE = NULL_STR;
Xstatic char  *SO = NULL_STR;
Xstatic char  *SE = NULL_STR;
Xstatic unsigned int Kb;
X
Xstatic int termtype;
X
X#define SMG$K_BEGIN_REVERSE     0x1bf
X#define SMG$K_END_REVERSE       0x1d6
X#define SMG$K_ERASE_TO_END_LINE 0x1d9
X
X
X/***
X *  tgetstr  -  Get an SMG string capability by name
X *
X *  Returns:  Escape sequence
X *    NULL  No escape sequence available
X ***/`032
Xstatic char *tgetstr(request_code)
Xint request_code;
X`123
X`009register char * result;
X`009static char seq_storage[1024];
X`009static char * buffer = seq_storage;
X`009static int arg_list[2] = `123 1, 1 `125;
X`009int max_buffer_length, ret_length;
X
X`009/*  Precompute buffer length */
X`009
X`009max_buffer_length = (seq_storage + sizeof(seq_storage)) - buffer;
X
X`009/* Get terminal commands sequence from master table */
X
X`009if ((smg$get_term_data(     /* Get terminal data   */
X`009`009`009       &termtype,         /* Terminal table address  */
X`009`009`009       &request_code,     /* Request code    */
X`009`009`009       &max_buffer_length,/* Maximum buffer length */
X`009`009`009       &ret_length,       /* Return length   */
X`009`009`009       buffer,            /* Capability data buffer  */
X`009`009`009       arg_list)          /* Argument list array */
X             & 1) == 0 &&`032
X`009    /* If that didn't work, try again with no arguments */
X
X`009    (smg$get_term_data(     /* Get terminal data    */
X`009`009`009       &termtype,         /* Terminal table address */
X`009`009`009       &request_code,     /* Request code     */
X`009`009`009       &max_buffer_length,/* Maximum buffer length */
X`009`009`009       &ret_length,       /* Return length    */
X`009`009`009       buffer)            /* Capability data buffer */
X`009     & 1) == 0)
X`009`009/* Return NULL pointer if capability is not available */
X`009`009return NULL;
X
X`009/* Check for empty result */
X`009if (ret_length == 0)
X`009`009return NULL;
X
X`009/* Save current position so we can return it to caller */
X`009result = buffer;
X
X`009/* NIL terminate the sequence for return */
X`009buffer[ret_length] = 0;
X
X`009/* Advance buffer */
X`009buffer += ret_length + 1;
X
X`009/* Return capability to user */
X`009return result;
X `125  /* tgetstr */
X
X
X /** I/O information block definitions **/
X typedef struct `123    /* I/O status block     */
X   short i_cond;     /* Condition value      */
X   short i_xfer;     /* Transfer count     */
X   long  i_info;     /* Device information     */
X `125 iosb;
X
X typedef struct `123    /* Terminal characteristics   */
X   char  t_class;    /* Terminal class     */
X   char  t_type;     /* Terminal type      */
X   short t_width;    /* Terminal width in characters   */
X   long  t_mandl;    /* Terminal's mode and length   */
X   long  t_extend;   /* Extended terminal characteristics  */
X `125 termchar;
X
X static termchar tc; /* Terminal characteristics   */
X
X
X /***
X  *  vmsgtty - Get terminal type from system control block
X  *
X  *  Nothing returned
X  ***/
X static void vmsgtty()
X `123
X`009 short fd;
X`009 int status;
X`009 iosb iostatus;
X
X`009 $DESCRIPTOR(devnam, "SYS$COMMAND");
X
X`009 /* Assign input to a channel */
X`009 status = sys$assign(&devnam, &fd, 0, 0);
X`009 if ((status & 1) == 0)
X`009`009 exit(status);
X
X`009 /* Get terminal characteristics */
X`009 status = sys$qiow(`009`009   /* Queue and wait   */
X`009`009`009   0,`009`009   /* Wait on event flag zero  */
X`009`009`009   fd,`009`009   /* Channel to input terminal  */
X`009`009`009   IO$_SENSEMODE,   /* Get current characteristic */
X`009`009`009   &iostatus,       /* Status after operation */
X`009`009`009   0, 0,            /* No AST service   */
X`009`009`009   &tc,             /* Terminal characteristics buf */
X`009`009`009   sizeof(tc),      /* Size of the buffer   */
X`009`009`009   0, 0, 0, 0);     /* P3-P6 unused     */
X
X`009 /* De-assign the input device */
X`009 if ((sys$dassgn(fd) & 1) == 0)
X`009`009 exit(status);
X
X`009 /* Jump out if bad status */
X`009 if ((status & 1) == 0)
X`009`009 exit(status);
X`009 if ((iostatus.i_cond & 1) == 0)
X`009`009 exit(iostatus.i_cond);
X `125  /* vmsgtty */
X
X
X /* Terminal_Open
X  *   Get terminal type and open terminal.
X */
X bool Terminal_Open()
X `123
X
X`009 smg$create_virtual_keyboard(&Kb);
X
X`009 /* Get terminal type */
X`009 vmsgtty();
X`009 if (tc.t_type == TT$_UNKNOWN)
X`009`009 return FALSE;
X
X`009 /* Access the system terminal definition table for the  */
X`009 /* information of the terminal type returned by IO$_SENSEMODE */
X`009 if ((smg$init_term_table_by_type(&tc.t_type, &termtype) & 1) == 0)
X`009`009 return FALSE;
X
X`009 /* Set sizes */
X`009 Screen_Height = ((unsigned int) tc.t_mandl >> 24);
X`009 Screen_Width = tc.t_width;
X
X`009 /* Get some capabilities */
X`009 SO = tgetstr(SMG$K_BEGIN_REVERSE);
X`009 SE = tgetstr(SMG$K_END_REVERSE);
X`009 CE = tgetstr(SMG$K_ERASE_TO_END_LINE);
X
X`009 setbuf(stdout, 0);
X
X`009 return TRUE;
X `125  /* Terminal_Open */
X
X
X /* ClrEOL
X      Clears from (and including) the current cursor position to the
X      end of the line.
X */
X void ClrEOL()
X `123
X`009 if (CE != NULL)
X`009`009 tputs(CE);
X`009 else
X`009 `123
X`009`009 int i;
X`009`009 for (i = 0; i < Screen_Width - 1; i++)
X`009`009`009 tputone(' ');
X`009`009 tputone('\r');
X`009 `125
X `125  /* ClrEOL */
X
X
X /* Ding
X      Rings the terminal's bell.
X */
X void Ding()
X `123
X`009 tputs(BEL_STR);
X `125  /* Ding */
X
X
X /* standout
X */
X void standout()
X `123
X`009 if (SO != NULL)
X`009`009 tputs(SO);
X `125  /* standout */
X
X
X /* standend
X */
X void standend()
X `123
X`009 if (SE != NULL)
X`009`009 tputs(SE);
X `125  /* standend */
X
X
X /* tputs
X */
X static void tputs(str)
X char *str;
X `123
X`009 int i;
X
X`009 if (str != NULL)
X`009 `123
X`009`009 i = 0;
X`009`009 while (str[i])
X`009`009`009 (void) write(1, &str[i++], 1);
X`009 `125
X `125  /* tputs */
X
X
X /* tputone
X */
X static void tputone(ch)
X char ch;
X `123
X`009 (void) write(1, &ch, 1);
X `125  /* tputone */
X
X
X /* -------------------------------------------------------------------- */
X
X /* getkey
X     Read in a keystroke in raw noecho mode.
X */
X int getkey()
X `123
X`009 static short int ch;
X
X`009 smg$read_keystroke(&Kb, &ch);
X`009 return ch;
X `125  /* getkey */
X
X
X /* -------------------------------------------------------------------- */
X
X /* fix_string
X     Fixes a string so that it doen't have any control characters in it,
X other than one at the end (\n).
X  */
X void fix_string(str)
X char *str;
X `123
X`009 int i;
X
X`009 for (i = 0; i < strlen(str) - 1; i++)
V`009`009 if ((! isprint(str[i]) && ! isspace(str[i])) `124`124 str[i] == '\f'
X)
X`009`009`009 str[i] = '.';
X `125
X
X /* -------------------------------------------------------------------- */
X /* str_lines
X     Determines how many lines a string would take up if it were printed.
X It assumes 8 space tabs (BAD).  It returns the number of extra lines that
X will be printed.  It also assumes that integer truncation will occur.
X  */
X int str_lines (str, width)
X char *str;
X `123
X`009 int spaces;
X`009 char *walker;
X
X`009 spaces = 0;
X`009 walker = str;
X`009 while (*walker)
X`009 `123
X`009`009 if (*walker == '\t')
X`009`009`009 spaces = ((spaces / 8) + 1) * 8; /* Int truncation */
X`009`009 else
X`009`009`009 spaces++;
X`009`009 walker++;
X`009 `125
X`009 if (*walker == '\n')
X`009`009 spaces--;
X
X`009 if (((spaces + width - 1) / width) - 1 < 0)
X`009 `123
X`009`009 fprintf (stderr, "We have a problem.... spaces = %d\n");
X`009`009return (0);
X`009`125
X
X`009return (((spaces + width - 1) / width) - 1);
X`125
X
Xmore_help()
X`123
X`009printf ("\n\n\t<SPACE>\t\tnext %d lines\n", Screen_Height - 2);
X`009puts ("\t<RETURN>\tnext line");
X`009puts ("\td\t\thalf a screen");
X`009puts ("\tb\t\tskip backward");
X`009puts ("\tt\t\ttop of the file");
X`009printf ("\ts\t\tskip over next %d lines\n", Screen_Height - 2);
X`009puts ("\th\t\tprint this message");
X`009puts ("\t/string\t\tsearch forward");
X`009puts ("\tn\t\trepeat last search");
X`009puts ("\t!\t\tspawn subprocess");
X`009puts ("\t#\t\tgo to the next file");
X`009puts ("\tq\t\tquit\n");
X`009standout ();
X`009printf (" press any key now to continue ");
X`009standend ();
X`009putchar (' ');
X`009getkey ();
X`125
X
X/* -------------------------------------------------------------------- */
X`012
X/**********************************************************************
X *     convert_unix_to_vms () --- Converts a unix file name to a vms
X * `009`009`009`009  file name.  THIS IS A HACK.  DOESN'T
X *                                UNDERSTAND `126user/ or ./xxx .  DON'T`032
X *                                BLAME ME, do you expect for thirty
X *                                minutes work??????
X * Warning:
X *`009THIS IS A TERRIBLE HACK TO GET THE JOB DONE.  I'M NOT PROUD
X * OF THIS CODE.  IT WASN'T PLANNED, IT JUST HAPPENED.  IT WAS DONE IN
X * A VERY AD-HOCK MANNOR THAT TRADED "official" UNIX syntax for something
X * close that a typical VMS/UNIX user may type.
X *
X * Arguments:
X *`032
X *     fn`009`009      -m- File name to frob.  This is done in
X * `009`009`009`009  place.
X */
X
Xchar *convert_unix_to_vms (fn)
Xchar *fn;
X`123
X`009register char *src, *dst;
X`009int len;
X`009static char buffer[MAXNAME];
X`009char *strchr();
X`009char *strrchr();
X`009
X`009src = fn;
X`009dst = buffer;
X`009
X`009if (*src == '`126')
X`009`123
X`009`009strcpy (dst, getenv ("HOME"));
X`009`009dst += strlen (dst);
X`009`009src += 1;
X`009`009if (*src == '/')
X`009`009`009src += 1;
X`009`009if (strchr (src, '/') != (char *) NULL)
X`009`009`009*(dst - 1) = '.';
X`009`125
X`009else if (*src == '/')
X`009`123
X`009`009*dst++ = '[';
X`009`009src += 1;
X`009`125
X`009else if (strchr (src, ':') != (char *) NULL)
X`009`123
X`009`009len = strchr (src, ':') - src + 1;
X`009`009strncpy (dst, src, len);
X`009`009dst += len;
X`009`009src += len;
X`009`009if (*src == '/')
X`009`009`009src++;
X`009`009*dst++ = '[';
X`009`125
X`009else
X`009`123
X`009`009if (*src == '.')
X`009`009`123
X`009`009`009*dst++ = '[';
X`009`009`125
X`009`009else
X`009`009`123
X`009`009`009strcpy (buffer, "[.");
X`009`009`009dst += 2;
X`009`009`125
X`009`125
X`009
X`009while (*src)
X`009`123
X`009`009if (strncmp ("../", src, 3) == 0)
X`009`009`123
X`009`009`009*dst++ = '-';
X`009`009`009src += 3;
X`009`009`009if (strchr (src, '/') == (char *) NULL)
X`009`009`009`009*dst++ = ']';
X`009`009`009continue;
X`009`009`125
X`009`009if (*src == '/')
X`009`009`123
X`009`009`009if (strchr (src + 1, '/') == (char *) NULL)
X`009`009`009`009*dst++ = ']';
X`009`009`009else
X`009`009`009`009*dst++ = '.';
X`009`009`009src += 1;
X`009`009`009continue;
X`009`009`125
X`009`009if (*(dst - 1) == '-' && *(src - 1) == '/')
X`009`009`009*dst++ = '.';
X`009`009*dst++ = *src++;
X`009`125
X`009dst = malloc (strlen (buffer) + 1);
X`009strcpy (dst, buffer);
X`009return dst;
X`125    /* end of convert_unix_to_vms () */
$ GOSUB UNPACK_FILE
$ EXIT
-+-+-+-+-+ End of part 2 +-+-+-+-+-
--
Warner Losh
warner@hydrovax.nmt.edu		...!unmvax!nmtsun!warner%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...

