KVC@BUSTER.NRC.COM (Kevin Carosso) (06/22/88)
...................... 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<num; ++i ) { /* go through the whole line * X/ X ch = twline[i]; /* get the current char */ X if ( (ch == LF && lastch >= 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 +-+-+-+-+-