Path: utzoo!attcan!uunet!husc6!mailrus!ames!pasteur!ucbvax!BUSTER.NRC.COM!KVC
From: KVC@BUSTER.NRC.COM (Kevin Carosso)
Newsgroups: comp.os.vms
Subject: USC PHOTO for new PTYs 1/2
Message-ID: <8806261719.AA15833@ucbvax.Berkeley.EDU>
Date: 21 Jun 88 23:41:00 GMT
Sender: daemon@ucbvax.BERKELEY.EDU
Organization: The Internet
Lines: 466
...................... Cut between dotted lines and save. .....................
$!.............................................................................
$! VAX/VMS archive file created by VMS_SHARE V06.00 26-May-1988.
$!
$! 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 KVC
$! on 14-OCT-1864 22:00:33.11.
$!
$! 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 6 files:
$! 000_README.TXT
$! PHOTO.C
$! PHOTO.CLD
$! PHOTO.HLP
$! PHOTO.README
$! PHOTOMSG.MSG
$!
$!==============================================================================
$ 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.00 26-May-1988 requires VMS V4.4 or higher."
$ EXIT 44
$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 ) ); 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 )
; IF CURRENT_CHARACTER = "`" THEN MOVE_HORIZONTAL( 1 ); ELSE COPY_TEXT( ASCII
( INT( ERASE_CHARACTER( 3 ) ) ) ); ENDIF; 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 = "000_README.TXT"
$ CHECKSUM_IS = 1953524851
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
XThis is a version of PHOTO modified to work with the new version
Xof the PY/TW drivers. It has been tested under both VMS V5.0 and
XVMS V4.7. This could use some work to clean it up and use the
Xnew features of the drivers.
X
XNote that PHY_IO privilege is required to properly propagate the
Xterminal characteristics, and PHOTO should therefore be installed
Xwith PHY_IO. If PHOTO is not installed and the user does not have
XPHY_IO, a warning message will be issued and the pseudo-terminal
Xwill not have the same characteristics as the user's real terminal.
XPHOTO will still produce a session log, however.
X
X`009/Kevin Carosso kvc@nrc.com
X`009 Network Research Co. kvc@ymir.bitnet
X
X`009June 9, 1988
$ GOSUB UNPACK_FILE
$ FILE_IS = "PHOTO.C"
$ CHECKSUM_IS = 1030740917
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X/* PHOTO.C
X *
X * Copyright 1986, University of Southern California
X * Author - Asbed Bedrossian
X * This program may be copied or distributed for any non-commercial
X * purpose, as long as this notice remains intact.
X *
X * This program is used to log a terminal session.
X *
X * Compile: CC PHOTO
X * MESSAGE PHOTOMSG
X * Link: LINK/NOTRACE PHOTO,PHOTOMSG,SYS$LIBRARY:CSHARE/OPT
X * Place: SYS$SYSTEM:
X * Install: INSTALL> ADD SYS$SYSTEM:PHOTO/PRIV=PHY_IO
X *
X * For proper execution, You will need to install CMU's PseudoTerminal (PTY)
X * driver on your system. You need PYDRIVER.EXE and TWDRIVER.EXE.
X * These drivers can be installed with the following SYSGEN commands:
X * SYSGEN> RELOAD SYS$SYSTEM:TWDRIVER
X * SYSGEN> CONNECT TWA0 /NOADAPTER
X * SYSGEN> RELOAD SYS$SYSTEM:PYDRIVER
X * SYSGEN> CONNECT PYA0 /NOADAPTER
X *
X */
X
X/*
XHistory:
X
XAsbed Bedrossian`0091986`009Created File.
X
XCharles Karney`009`0091987`009Spawn child process to be name Photo_xxxxxx
X
XBob Sloane`009`0091987`009Added the IO$M_ESCAPE modifier to the QIO to
X`009`009`009`009read from the terminal and the problem went
X`009`009`009`009away. I also fixed up my code in log_line so
X`009`009`009`009that it will handle CR/LF and LF/CR pairs
X`009`009`009`009spread across lines.
X
XChris Ho, USC`009`0091988`009Fix privileges after DEC security patch v2.
X
XKevin Carosso, NRC`0099-JUN-1988
X`009`009`009`009Modify for new PY/TW driver set. Change
X`009`009`009`009the name of the pseudo-terminal from TZA
X`009`009`009`009to TWA. Change SENSEMODE to $GETDVI to
X`009`009`009`009get unit number in DEVDEPEND. If we
X`009`009`009`009don't have PHY_IO, issue warning but
X`009`009`009`009don't exit. For now, ignore SS$_DATAOVERUN
X`009`009`009`009return on writes to the PY. We really should
X`009`009`009`009watch the delivered char count in the IOSB
X`009`009`009`009and wait for an XON AST.
X*/
X
X#include DESCRIP
X#include FAB
X#include IODEF
X#include RAB
X#include TTDEF
X#include TT2DEF
X#include stdio
X#include JPIDEF
X#include SSDEF
X#include PRCDEF
X#include PRVDEF
X#include DVIDEF
X
X#define CR 13
X#define LF 10
X#define logchar 28 /* Logging on/off flag ^\ */
X#define timchar 29 /* Time logging flag ^] */
X#define ttchrlen 12
X#define twdevlen 15
X#define mbsiz 40
X#define maxsiz 80
X#define linesz 512
X
X#define bad(j) !((j) & 1)
X#define check(a) if (bad(st = (a))) LIB$SIGNAL(st)
X#define garbage(a) ((a) == CR) || ((a) == LF) || (!(a))
X
X
X
X
X
X
X
X
X
Xglobalvalue PHOTO_INUSE;
X
Xstruct CHARBLK {unsigned char class,
X ttype;
X unsigned short pgwid;
X unsigned ttchr : 24;
X unsigned char pglen;
X unsigned int xchar;
X };
X
Xstruct IOSBBLK {unsigned short stats,
X tmoff,
X tmntr,
X tmsiz;
X };
X
Xtypedef struct DVIBLK {
X`009unsigned short`009len, code;
X`009char`009* buffp;
X`009long`009* lenp;
X`009long`009terminate;
X`009} DVIBLK;
X
Xlong py_chn, py_mb_chn,
X tt_chn, tt_mb_chn,
X pid,st,line_index=0;
X
Xchar finaltw[twdevlen],
X line[linesz]=0, time[24],
X py_mb[mbsiz], tt_mb[mbsiz],
X ttline[linesz], twline[linesz],
X tim= 0, com= 0, log= 1, enable_hangups= 0;
X
Xstruct CHARBLK tt_chr, tt_sav_chr;
Xstruct IOSBBLK tiosb, piosb, miosb;
Xstruct FAB zfab;
Xstruct RAB zrab;
X
X
X
X
X
X
X
X
X
Xquit() /* This is done upon exiting, by exit handler */
X{
X int j;
X
X j= SYS$DELMBX(py_mb_chn);
X if (bad(j))
X puts ("[SYS$DELMBX pseudo-mbx deletion failed]");
X j= SYS$QIOW(0,tt_chn,IO$_SETMODE,0,0,0,&tt_sav_chr,ttchrlen,0,0,0,0);
X if (bad(j))
X puts ("[SYS$QIO /setmode/ failed]");
X puts ("\nEnd PHOTO session");
X}
X
X
X
X
X
X
X
X
X
Xlow_lib_spawn(pty_io,pid) /* Spawns subprocess to speaks to pseudo terminal */
X char *pty_io;
X int *pid;
X{
X long prv[2], oprv[2];
X int my_pid, owner, item;
X char procnm[16], ownprc[16];
X
X $DESCRIPTOR(d_procnm, procnm);
X $DESCRIPTOR(d_pty_io, pty_io); /* PTY name + number */
X
X my_pid = getpid ();
X/*
X * check to see if we are already in PHOTO
X */
X check (LIB$GETJPI (&JPI$_PRCNAM,0, 0, 0, &d_procnm) );
X check (LIB$GETJPI (&JPI$_OWNER, 0, 0, &owner) );
X sprintf (ownprc, "PHOTO_%04X", owner & 0xFFFF);
X if (! strncmp (ownprc, procnm, 10) )
X`009return PHOTO_INUSE;
X
X sprintf (procnm, "PHOTO_%04X", my_pid & 0xFFFF);
X d_procnm.dsc$w_length = 10;
X d_pty_io.dsc$w_length = strlen (pty_io);
X
X prv[0] = prv[1] = -1;
X check (SYS$SETPRV (0, prv, 0, oprv) );`009/* disable image privs */
X check (LIB$GETJPI (&JPI$_PROCPRIV, 0, 0, prv) );
X check (SYS$SETPRV (1, prv, 0, 0) );`009`009/* enable normal privs */
X
X st = LIB$SPAWN (0, &d_pty_io, &d_pty_io, &1, &d_procnm, pid);
X if (st & SS$_NORMAL)
X`009check (SYS$SETPRV (1, oprv, 0, 0) );`009/* enable image privs */
X return st;
X}
X
X
X
X
X
X
X
X
X
Xasctim() /* Returns Time-stamp info */
X{
X char buf[24];
X $DESCRIPTOR(d_asctim,&buf);
X
X check(SYS$ASCTIM(0,&d_asctim,0,0));
X buf[20]= 0;
X sprintf(&time,"[%s]",&buf);
X}
X
X
X
X
X
X
X
X
X
Xtoggle(swtch) /* Set switches as desired */
X char swtch;
X{
X char buf[40];
X
X if (swtch == logchar) {
X log= !log;
X if (log)
X sprintf(&buf,"Logging has been ENABLED\r\n");
X else
X sprintf(&buf,"Logging has been DISABLED\r\n");
X }
X else {
X tim= !tim;
X if (tim)
X sprintf(&buf,"Time stamping has been ENABLED\r\n");
X else
X sprintf(&buf,"Time stamping has been DISABLED\r\n");
X }
X check(SYS$QIOW(0,tt_chn,IO$_WRITEVBLK,0,0,0,&buf,strlen(&buf),0,0,0,0));
X}
X
X
X
X
X
X
X
X
X
Xtw_srv() /* AST: on pseudo terminal. Deals with spurious hangups */
X{
X check(miosb.stats);
X if (enable_hangups)
X exit(1);
X else
X check(SYS$QIO(0,py_mb_chn,IO$_READVBLK,&miosb,&tw_srv,0,
X &py_mb,mbsiz,0,0,0,0));
X}
X
X
X
X
X
X
X
X
X
Xtt_srv() /* AST: Read on real terminal */
X{
X int j;
X
X check(tiosb.stats);
X /* Read everything typed right away */
X check(SYS$QIOW(0,tt_chn,IO$_READVBLK|IO$M_TIMED|IO$M_ESCAPE,&tiosb,0,0,
X &ttline,linesz,0,0,0,0));
X j= tiosb.tmoff + tiosb.tmsiz; /* How many chars read */
X com= ttline[0]==CR;
X if (com) {
X if (tim) asctim(); /* Time stampi info */
X }
X else
X if ((ttline[0] == logchar) || (ttline[0] == timchar)) /* flags */
X toggle(ttline[0]);
X /* write everything we read to pseudo-terminal */
X check(SYS$QIOW(0,py_chn,IO$_WRITEVBLK,&tiosb,0,0,&ttline,j,0,0,0,0));
X if (tiosb.stats != SS$_DATAOVERUN)
X`009check(tiosb.stats);
X /* re-post read AST on real term */
X check(SYS$QIO(0,tt_mb_chn,IO$_READVBLK,&tiosb,&tt_srv,0,
X &tt_mb,mbsiz,0,0,0,0));
X}
X
X
X
X
X
X
X
X
X
Xint lastch = -1; /* holds last character processed for
X CR/LF or LF/CR processing. <0 means
X this is the first line to avoid a null
X line at the start of the file */
Xlog_line(num) /* This logs the input into a file */
X int num;
X{
X int i; /* counter var */
X char ch; /* current character */
X
V for ( i=0; i= 0 ) /* if starting a new line */
X || line_index >= linesz-1 ) { /* or the buffer is full */
X zrab.rab$l_rbf= &line; /* set up to write line */
X zrab.rab$w_rsz= line_index;
X check(SYS$PUT(&zrab,0,0)); /* write line into file */
X if ((com) && (tim)) { /* are we Time-stamping? */
X zrab.rab$l_rbf= &time;
X zrab.rab$w_rsz= strlen(&time);
X check(SYS$PUT(&zrab,0,0)); /* Time-stamp in file */
X }
X line_index = 0; /* start the new line */
X line[line_index] = 0; /* make sure it has an EOS */
X }
X if ( (lastch == LF || lastch < 0) && ch == CR ) /* CR starting line? */
X continue; /* yes - ignore it */
X if ( lastch == CR && ch != LF ) { /* check for CR/LF pair */
X line[line_index++] = CR; /* not CR/LF pair, file it */
X line[line_index] = 0; /* make line a C string */
X }
X if ( ch != LF && ch != CR ) { /* don't want these on file */
V line[line_index++] = ch; /* add the character to line *
X/
X line[line_index] = 0; /* and the EOS */
X }
X lastch = ch; /* remember the last char */
X }
X}
X
X
X
X
X
X
X
X
X
Xget_file(filspec) /* Sets up a file RAB and FAB */
X char *filspec;
X{
X zfab= cc$rms_fab;
X zrab= cc$rms_rab;
X zfab.fab$b_fac= FAB$M_GET+FAB$M_PUT;
X zfab.fab$l_fna= filspec;
X zfab.fab$b_fns= strlen(filspec);
X zfab.fab$b_org= FAB$C_SEQ;
X zfab.fab$b_rat= FAB$M_CR;
X zfab.fab$b_rfm= FAB$C_VAR;
X zfab.fab$b_shr= FAB$M_SHRPUT | FAB$M_SHRGET | FAB$M_UPI;
X check(SYS$CREATE(&zfab,0,0));
X zrab.rab$l_fab= &zfab;
X zrab.rab$w_isi= 0;
X zrab.rab$l_rop= RAB$M_EOF;
X check(SYS$CONNECT(&zrab, 0, 0));
X zrab.rab$b_rac= RAB$C_SEQ;
-+-+-+-+-+ End of part 1 +-+-+-+-+-