From:	CSBVAX::MRGATE!BRIAN%UOFT02.BITNET@CUNYVM.CUNY.EDU@SMTP 19-MAR-1988 09:52
To:	ARISIA::EVERHART
Subj:	RE: Clarification ..


Received: from CUNYVM.CUNY.EDU by KL.SRI.COM with TCP; Fri 18 Mar 88 02:27:13-PST
Received: from CUNYVM.BITNET by CUNYVM.CUNY.EDU ; Fri, 18 Mar 88 05:27:05 EST
X-Delivery-Notice:  SMTP MAIL FROM does not correspond to sender.
Received: from UOFT02 (smtpuser) by CUNYVM.BITNET (Mailer X1.25) with BSMTP id
 8851; Fri, 18 Mar 88 05:26:50 EST
Date: Fri, 18 Mar 88 05:22 EST
From: Brian Nelson <BRIAN%UOFT02.BITNET@CUNYVM.CUNY.EDU>
Subject: RE: Clarification ..
To: INFO-VAX@KL.SRI.COM
X-VMS-To: IN%"INFO-VAX@KL.SRI.COM",BRIAN



/*      PACX_LOGGER     Log message from PACX 4 to logging terminal
                        and disk file.

        System:         VAX VMS version 4.2
        Author:         Brian Nelson, 31-JAN-1986 13:51

        Logical names:  ASS/SYS TXA4: PACX_STAT_OUT
                        ASS/SYS TXA5: PACX_STAT_DISPLAY
                        ASS/SYS DUA1:[SYS0.PACX_DATA] PACX_STAT_LOGDIR

        Where:          TXA4 (DMF32) is connected directly to the STAT port
                        TXA5 (DMF32) is connected to real time VT100 terminal
                        via a NULL modem
                        PACX_STAT_LOGDIR:PACX_LOG.DATA is the name of log file

                        To avoid ever getting TXA4 to try to run LOGINOUT you
                        should do: SET TER TXA4:/PERM/SECURE/SPEED=2400/NOAUTO

        Data is never written to the log file until 20 messages are buffered.
        Thus, you can rename the file to get it to create a new one. It would
        be a good idea to set a timer ast to dump every hour or two during
        periods of low activity, but that can come later.
        A timer has been added to create a new logfile every night at 12:00

        The input line, in this case TXA4 which is assigned as the equvilence
        string to the logical name PACX_STAT_OUT, is set at startup as in:

        $ set ter txa4:/perm/secure/speed=2400

        Setting the SECURE characteristic is a crude way of disabling the
        line from LOGINS from data being sent to the vax before startup is
        complete.

        Startup:        run sys$utility:pacx_logger/uic=[1,4]/det

*/

#include        <opcdef>
#include        <iodef>
#include        <stdio.h>
#include        <descrip.h>
#include        <prvdef.h>
#include        <ssdef.h>
#define then

#ifndef LNM$_STRING
#define LNM$_STRING     2
#define LNM$_ATTRIBUTES 3
#define LNM$M_TERMINAL  512
#define LNM$M_CASE_BLIND 33554432
#endif











FILE *logfile ;

union  pointer  {
                int  *intbuf ;
                char *charbuf ;
                } ;

struct itmlst   {
                unsigned short int bufferlength ;
                unsigned short int item_code ;
                union pointer  addr ;
                int  *retlength ;
                } ;

struct dsc      {
                int len ;
                char *addr ;
                } ;

extern char *strcpy(), *strcat() ;

int read_lun,write_lun ;

char logfilename[] = "PACX_STAT_LOGDIR:PACX_LOG.DATA" ;

#define MAXMSG 20
#define MSGBUFSIZE 120
char *msgbuf[MAXMSG+1] ;
int curmsg ;

int ast_happened ;











main()
{

        $DESCRIPTOR(midnite_dsc,"-- 23:59:59.00") ;
        $DESCRIPTOR(deltatime_dsc,"0 00:00:00.20") ;
        $DESCRIPTOR(procname,"Pacx_Logger") ;

        extern char *ctime(),*malloc() ;
        extern int  *time() ;
        char *cp, fmsg[100], read_buffer[80], write_buffer[MSGBUFSIZE] ;
        int curtime,i,status ;
        unsigned int waittime[2], midnite[2] ;
        int newfile() ;

        ast_happened = 1 ;
        curmsg = 0 ;
        for ( i=0;i < MAXMSG; i++ ) msgbuf[i] = malloc(MSGBUFSIZE) ;

        sys$bintim(&deltatime_dsc,&waittime) ;
        sys$bintim(&midnite_dsc,&midnite) ;
        sys$setimr(0,&midnite,newfile,0) ;
        sys$setprn(&procname) ;

        strcpy(fmsg,logfilename) ;
        sendopcom("PACX Logger waiting to allocate terminal lines....") ;
        while ( ( openterm() & 1 ) == 0 ) sleep(1) ;
        sendopcom("PACX Logger allocatted terminals, starting....") ;
        if ( openlog(logfilename) & 1 )
          then {
                sendopcom(strcat(fmsg," opened....")) ;
                fputs("Log file opened\n",logfile) ;
                closelog() ;
               }
          else  sendopcom(strcat(fmsg," not opened....")) ;

        while (1) {
          if ( (status=read_pacx(read_buffer)) & 1 )
            then {
                time(&curtime) ;
                strcpy(write_buffer,ctime(&curtime)) ;
                strcat(write_buffer,"  ") ;
                strcat(write_buffer,read_buffer) ;
                cp = write_buffer ;
                while ( *cp ) { if (*cp < '\037') *cp = ' '; cp++; } ;
                write_log(write_buffer) ;
                } ;
          sys$schdwk(0,0,&waittime,0) ;
          sys$hiber() ;
        } ;
}











read_pacx(s)
char *s ;
{
        short int iosb[4] ;
        int status ;

        status=sys$qiow(0,read_lun,IO$_READVBLK,&iosb,0,0,s,80,0,0,0,0);
        if ( ( status & 1 ) == 0 ) then return( status ) ;
        *(s+iosb[1]) = 0 ;
        return(1) ;
}

write_log(s)
{
        int i,status ;
        char fmt[4] ;

        fmt[0] = 040 ;
        status=sys$qio(2,write_lun,IO$_WRITEVBLK,0,0,0,s,strlen(s),0,fmt,0,0);
        strcat(strcpy(msgbuf[curmsg],s),"\n") ;
        if ( ++curmsg >= MAXMSG ) {
          curmsg = 0 ;
          openlog(logfilename) ;
          if (logfile != NULL)
            then for (i=0; i < MAXMSG; i++ ) fputs(msgbuf[i],logfile) ;
          closelog() ;
          } ;
        if ( ( status & 1 ) == 0 ) then return( status ) ;
        return(1) ;
}


newfile()
{
        $DESCRIPTOR(next_ast,"1 00:00:00.00") ;
        unsigned int bintim[2] ;

        sys$bintim(&next_ast,&bintim) ;
        sys$setimr(0,&bintim,newfile,0) ;
        ast_happened = 1 ;
}

openlog(s)
char *s ;
{
        FILE *fopen() ;
        char mode[2] ;
        int status ;

        sys$setast(0) ;
        mode[1] = 0 ;
        mode[0] = ( ast_happened ) ? 'w' : 'a' ;
        ast_happened = 0 ;
        status = ( (logfile=fopen(s,mode)) != NULL ) ;
        sys$setast(1) ;
        return( status ) ;
}

closelog()
{
        if ( logfile != NULL) fclose( logfile ) ;
        return(1) ;
}











openterm()
{
        $DESCRIPTOR(sysdesc,"LNM$SYSTEM_TABLE") ;
        $DESCRIPTOR(data_in,"PACX_STAT_OUT") ;
        $DESCRIPTOR(data_out,"PACX_STAT_DISPLAY") ;
        struct itmlst trnlist[3] ;
        int attr_arg, status ;
        char log_tran[20] ;
        struct dsc term_name ;

        term_name.addr = &log_tran ;
        attr_arg = LNM$M_CASE_BLIND ;
        trnlist[0].bufferlength = 4 ;
        trnlist[0].item_code    = LNM$_STRING ;
        trnlist[0].addr.charbuf = term_name.addr ;
        trnlist[0].retlength    = &term_name.len ;
        trnlist[1].bufferlength = 0 ;
        trnlist[1].item_code    = 0 ;

        status = sys$trnlnm(&attr_arg,&sysdesc,&data_out,0,&trnlist) ;
        if ( status == SS$_NOLOGNAM ) then return(0) ;
        if ( ( status & 1 ) == 0 ) then return( status );
        term_name.len &= 0377 ;
        if ( ( (status = sys$assign(&term_name,&write_lun,0,0)) & 1 ) == 0 )
          then return( status ) ;

        status = sys$trnlnm(&attr_arg,&sysdesc,&data_in,0,&trnlist) ;
        if ( status == SS$_NOLOGNAM ) then return(0) ;
        if ( ( status & 1 ) == 0 ) then return( status );
        term_name.len &= 0377 ;
        if ( ( (status = sys$assign(&term_name,&read_lun,0,0)) & 1 ) == 0 )
          then return( status ) ;

        return(1) ;
}











sendopcom(s)
char *s ;

/*      Send a asciz message to opcom                                   */
{

        struct opcfmt {
                        unsigned char type ;
                        short int target_0_15 ;
                        unsigned char target_16_23 ;
                        unsigned long rqstid ;
                        char msg[80] ;
                      } ;

        struct opcfmt msgdsc ;
        struct dsc opmsg = { 80,&msgdsc } ;
        int reply_chan,status ;

        reply_chan = 0 ;
        msgdsc.type = OPC$_RQ_RQST ;
        msgdsc.target_0_15 = OPC$M_NM_CENTRL ;
        msgdsc.target_16_23 = 0 ;
        msgdsc.rqstid = 0 ;
        strcpy(msgdsc.msg,s) ;
        opmsg.len = 8 + strlen(msgdsc.msg) ;
        opmsg.addr = &msgdsc ;
        return( sys$sndopr(&opmsg,reply_chan) ) ;

}

