From:	MERC::"uunet!WKUVX1.BITNET!FILESERV-Mgr" 12-JUN-1992 15:41:13.61
To:	galaxy::gleeve
CC:	
Subj:	JOBLOG.03_OF_07

-+-+-+-+-+-+-+-+ START OF PART 3 -+-+-+-+-+-+-+-+
X   fill = sense_iosb.cr_fill `7C (sense_iosb.lf_fill << 8);
X
X   status = SYS$QIO(0,tt_chan,IO$_SETMODE,&set_iosb,0,0,&dev_char,
X`09`09    sizeof(dev_char),speed,fill,sense_iosb.parity,0);
X
X   if(!(status & SS$_NORMAL))
X      LIB$STOP(status);
X
X   return;
X
X`7D`09/*** dev_chg_ast ***/
X`0C
X/***************************************************************************
V****
X****************************************************************************
V****
X
X  Function:`09bell_ast
X
X  Purpose:`09Called when the FT device wants to tell the user to stop
X`09`09sending input.  Just send a bell to the TTY.  If it fails it
X`09`09isn't resent since this really isn't all that crucial.
X
X  Formal Parameters:
X
X`09Name`09`09`09Description
X`09----`09`09`09-----------
X`09none
X
X  Global variables:
X
X`09Name`09`09`09Examine/Modify/Use/Read/Write
X`09----`09`09`09-----------------------------
X`09tt_chan`09`09`09`09`09X
X
X  Return Codes:
X
X`09Code`09 `09`09Reason
X`09----`09`09`09------
X`09none
X
X****************************************************************************
V****
X****************************************************************************
V***/
X
Xstatic void bell_ast(void)
X
X`7B`09/*** bell_ast ***/
X`09`09`09`09`09/********   LOCAL  VARIABLES   ********/
Xstatic`09 USHORT`09  bell_char = BELL;`09/* char to write to the TTY`09
V      */
X
X
X   bell_char = BELL;
X   SYS$QIO(0,tt_chan,IO$_WRITEVBLK,0,0,0,&bell_char,1,0,0,0,0);
X   return;
X
X`7D`09/*** bell_ast ***/
X`0C
X/***************************************************************************
V****
X****************************************************************************
V****
X
X  Function:`09xon_ast
X
X  Purpose:`09Called when XON is detected on the FT device.  Send an
X`09`09XON to the TTY.  If it fails it isn't resent since this
X`09`09really isn't all that crucial.
X
X  Formal Parameters:
X
X`09Name`09`09`09Description
X`09----`09`09`09-----------
X`09none
X
X  Global variables:
X
X`09Name`09`09`09Examine/Modify/Use/Read/Write
X`09----`09`09`09-----------------------------
X`09tt_chan`09`09`09`09`09X
X
X  Return Codes:
X
X`09Code`09 `09`09Reason
X`09----`09`09`09------
X`09none
X
X****************************************************************************
V****
X****************************************************************************
V***/
X
Xstatic void xon_ast(void)
X
X`7B`09/*** xon_ast ***/
X`09`09`09`09`09/********   LOCAL  VARIABLES   ********/
Xstatic`09 USHORT`09  xon_char = XON;`09/* char to write to the TTY`09      *
V/
X
X
X   xon_char = XON;
X   SYS$QIO(0,tt_chan,IO$_WRITEVBLK,0,0,0,&xon_char,1,0,0,0,0);
X   return;
X
X`7D`09/*** xon_ast ***/
X`0C
X/***************************************************************************
V****
X****************************************************************************
V****
X
X  Function:`09xoff_ast
X
X  Purpose:`09Called when XOFF is detected on the FT device.  Send an
X`09`09XOFF to the TTY.  If it fails it isn't resent since this
X`09`09really isn't all that crucial.
X
X  Formal Parameters:
X
X`09Name`09`09`09Description
X`09----`09`09`09-----------
X`09none
X
X  Global variables:
X
X`09Name`09`09`09Examine/Modify/Use/Read/Write
X`09----`09`09`09-----------------------------
X`09tt_chan`09`09`09`09`09X
X
X  Return Codes:
X
X`09Code`09 `09`09Reason
X`09----`09`09`09------
X`09none
X
X****************************************************************************
V****
X****************************************************************************
V***/
X
Xstatic void xoff_ast(void)
X
X`7B`09/*** xoff_ast ***/
X`09`09`09`09`09/********   LOCAL  VARIABLES   ********/
Xstatic`09 USHORT`09  xoff_char = XOFF;`09/* char to write to the TTY`09
V      */
X
X
X   xoff_char = XOFF;
X   SYS$QIO(0,tt_chan,IO$_WRITEVBLK,0,0,0,&xoff_char,1,0,0,0,0);
X   return;
X
X`7D`09/*** xoff_ast ***/
X`0C
X/***************************************************************************
V****
X****************************************************************************
V****
X
X  Function:`09write_ft
X
X  Purpose:`09Write data from TTY to the FT device.
X
X  Formal Parameters:
X
X`09Name`09`09`09Description
X`09----`09`09`09-----------
X`09ft_chan`09`09`09channel to write to
X`09ft_buf`09`09`09buffer to write
X
X  Global variables:
X
X`09Name`09`09`09Examine/Modify/Use/Read/Write
X`09----`09`09`09-----------------------------
X`09none
X
X  Return Codes:
X
X`09Code`09 `09`09Reason
X`09----`09`09`09------
X`09iosb->status`09`09error return in I/O status block
X`09SS$_NORMAL
X
X****************************************************************************
V****
X****************************************************************************
V***/
X
Xstatic ULONG write_ft(USHORT ft_chan,FT_BUF *ft_buf)
X
X`7B`09/*** write_ft ***/
X`09`09`09`09`09/********   LOCAL  VARIABLES   ********/
Xregister ULONG`09  status;`09`09/* return code status holder`09      */
X
X
X   status = PTD$WRITE(ft_chan,0,0,ft_buf,ft_buf->count,0,0);
X
X   if(status != SS$_NORMAL && status != SS$_DATAOVERUN)
X   `7B
X      LIB$SIGNAL(status);
X      return(status);
X   `7D
X
X   if(ft_buf->status != SS$_NORMAL && ft_buf->status != SS$_DATAOVERUN)
X   `7B
X      LIB$SIGNAL(ft_buf->status);
X      return(ft_buf->status);
X   `7D
X
X   return(SS$_NORMAL);
X
X`7D`09/*** write_ft ***/
X`0C
X/***************************************************************************
V****
X****************************************************************************
V****
X
X  Function:`09write_tt
X
X  Purpose:`09Write to the TTY
X
X  Formal Parameters:
X
X`09Name`09`09`09Description
X`09----`09`09`09-----------
X`09channel`09`09`09channel to write to
X`09buffer`09`09`09buffer to write
X`09length`09`09`09length of buffer to write`09
X
X  Global variables:
X
X`09Name`09`09`09Examine/Modify/Use/Read/Write
X`09----`09`09`09-----------------------------
X`09none
X
X  Return Codes:
X
X`09Code`09 `09`09Reason
X`09----`09`09`09------
X`09status`09`09`09from SYS$QIO or IOSB of write to TTY
X
X  Termination Codes:
X
X`09Code`09`09`09Reason
X`09----`09`09`09------
X`09none
X
X****************************************************************************
V****
X****************************************************************************
V***/
X
Xstatic ULONG write_tt(short channel,char *buffer,ULONG length)
X
X`7B`09/*** write_tt ***/
X`09`09`09`09`09/********   LOCAL  VARIABLES   ********/
Xstatic`09 ULONG`09  status;`09`09/* return code status holder`09      */
Xstatic`09 IOSB_DEF iosb;`09`09`09/* I/O status block`09`09      */
X
X
X   status = SYS$QIOW(0,channel,IO$_WRITEVBLK,&iosb,0,0,buffer,length,0,0,0,0
V);
X
X   if(!(status & SS$_NORMAL))
X      return(status);
X
X   if(iosb.status != SS$_NORMAL)
X      return(iosb.status);
X
X   /* make sure the right number of characters were written */
X
X   if((ULONG) iosb.count != length)
X      return(SS$_NOWRT);`09`09/* didn't write the right amount      */
X
X   return(SS$_NORMAL);
X
X`7D`09/*** write_tt ***/
X`0C
X/***************************************************************************
V****
X****************************************************************************
V****
X
X  Function:`09get_stamp
X
X  Purpose:`09Create the time stamp string.
X
X  Formal Parameters:
X
X`09Name`09`09`09Description
X`09----`09`09`09-----------
X`09stamp_buf`09`09where to put time stamp string
X
X  Global variables:
X
X`09Name`09`09`09Examine/Modify/Use/Read/Write
X`09----`09`09`09-----------------------------
X`09none
X
X  Return Codes:
X
X`09Code`09 `09`09Reason
X`09----`09`09`09------
X`09stamp_buf`09`09pointer to where time stamp is
X
X  Termination Codes:
X
X`09Code`09`09`09Reason
X`09----`09`09`09------
X`09status`09`09`09return code from SYS$ASCTIM if it fails
X
X****************************************************************************
V****
X****************************************************************************
V***/
X
Xstatic char *get_stamp(char *stamp_buf)
X
X`7B`09/*** get_stamp ***/
X`09`09`09`09`09/********   LOCAL  VARIABLES   ********/
Xstatic`09 ULONG`09  status;`09`09/* return code status holder`09      */
Xstatic`09 char`09  time_buf`5BTIME_MAX+1`5D;`09/* array for holding time str
Ving      */
Xstatic $DESCRIPTOR(time_d,time_buf);`09/* for getting time value`09      */
X
X
X   status = SYS$ASCTIM(0,&time_d,0,0);
X
X   if(!(status & SS$_NORMAL))
X      LIB$STOP(status);
X
X   time_buf`5Btime_d.dsc$w_length`5D = '\0';
X   cat(stamp_buf,"`5B",time_buf,"`5D");
X
X   return(stamp_buf);`09`09`09/* return pointer to time stamp str.  */
X
X`7D`09/*** get_stamp ***/
X`0C
X/***************************************************************************
V****
X****************************************************************************
V****
X
X  Function:`09write_log
X
X  Purpose:`09Write the specified line to the log file.
X
X  Formal Parameters:
X
X`09Name`09`09`09Description
X`09----`09`09`09-----------
X`09line`09`09`09buffer to be written
X`09length`09`09`09length of buffer to be written
X`09log_rab`09`09`09RAB of log file
X`09flags`09`09`09current flag structure
X
X  Global variables:
X
X`09Name`09`09`09Examine/Modify/Use/Read/Write
X`09----`09`09`09-----------------------------
X`09stamp_buf`09`09`09`09X`09  X
X
X  Return Codes:
X
X`09Code`09 `09`09Reason
X`09----`09`09`09------
X`09none
X
X  Termination Codes:
X
X`09Code`09`09`09Reason
X`09----`09`09`09------
X`09status`09`09`09write to log file failed
X
X****************************************************************************
V****
X****************************************************************************
V***/
X
Xstatic void write_log(char *line,USHORT length,struct RAB *log_rab,
X`09`09      FLAG_DEF *flags)
X
X`7B`09/*** write_log ***/
X`09`09`09`09`09/********   LOCAL  VARIABLES   ********/
Xregister ULONG`09  status;`09`09/* return code status holder`09      */
Xregister USHORT`09  i;`09`09`09/* loop and array index`09`09      */
Xstatic`09 USHORT`09  buf_cnt = 0;`09`09/* number of characters in buffer
V     */
Xstatic`09 char`09  rec_buf`5BMAX_REC+1`5D,`09/* for constructing record to w
Vrite   */
X`09`09  ch,`09`09`09/* for saving current character`09      */
X`09`09  lastch = -1;`09`09/* last character`09`09      */
X
X
X   for (i = 0; i < length; i++)
X   `7B
X      ch = line`5Bi`5D;                          /* get the current char */
X
X      if((ch == LINE_FEED && lastch >= 0) `7C`7C buf_cnt >= MAX_REC - 1)
X      `7B
X`09 /* either starting a new line or the buffer is full */
X
X`09 log_rab->rab$l_rbf= &rec_buf;`09/* set up to write line`09`09      */
X         log_rab->rab$w_rsz= buf_cnt;
X
X         status = SYS$PUT(log_rab,0,0);
X
X`09 if(status != RMS$_NORMAL)
X`09 `7B
X`09    kill_log();
X`09    LIB$STOP(status);
X`09 `7D
X
X         if(flags->command && flags->time_stamp)
X`09 `7B
X`09    /* write the time stamp to the file */
X
X`09    log_rab->rab$l_rbf= &stamp_buf;
X            log_rab->rab$w_rsz= strlen(stamp_buf);
X
X            status = SYS$PUT(log_rab,0,0);
X
X`09    if(status != RMS$_NORMAL)
X`09       LIB$STOP(status);
X
X`09    flags->command = FALSE;
X`09 `7D
X
X`09 buf_cnt = 0;`09`09`09/* start the new line`09`09      */
X`09 rec_buf`5B0`5D = '\0';`09`09/* make it a string`09`09      */
X      `7D
X`20
X      /* CR starting line? */
X
X      if((lastch == LINE_FEED `7C`7C lastch < 0) && ch == CARRIAGE_RETURN)
X         continue;`09`09`09/* yes, ignore it`09`09      */
X
X      /* don't want these in file (is this the way it should be???) */
X
X      if(ch != LINE_FEED && ch != CARRIAGE_RETURN && ch != 0)
X      `7B
X`09 rec_buf`5Bbuf_cnt++`5D = ch;
X`09 rec_buf`5Bbuf_cnt`5D = '\0';
X      `7D
X
X      lastch = ch;`09`09`09/* remember the last character`09      */
X   `7D
X
X   return;
X
X`7D`09/*** write_log ***/
X`0C
X/***************************************************************************
V****
X****************************************************************************
V****
X
X  Function:`09log_session
X
X  Purpose:`09This is actually the heart of the program.   Reads are
X`09`09done on the FT device asynchronously and the data is written
X`09`09to the TTY and the log file if logging is enabled.
X`09`09to read data from the FT device and write the data to the TTY
X  Formal Parameters:
X
X`09Name`09`09`09Description
X`09----`09`09`09-----------
X`09ft_chan`09`09`09channel to FT device
X`09tt_chan`09`09`09channel to TTY device
X
X  Global variables:
X
X`09Name`09`09`09Examine/Modify/Use/Read/Write
X`09----`09`09`09-----------------------------
X`09mess_d`09`09`09`09  X`09X
X`09tt_read_iosb`09`09`09`09X
X`09stamp_buf`09`09`09`09X
X`09ft_efn`09`09`09`09`09X
X`09flags`09`09`09   X`09  X
X`09tt_r_efn`09`09`09`09X
X`09wait_efn`09`09`09`09X
X`09bintim`09`09`09`09`09X
X`09ft_buf`09`09`09   X`09`09X
X`09tt_buf`09`09`09   X`09`09X
X`09cr_buf`09`09`09`09  X`09X
X`09term_block`09`09`09`09X
X
X  Return Codes:
X
X`09Code`09 `09`09Reason
X`09----`09`09`09------
X`09none
X
X  Termination Codes:
X
X`09Code`09`09`09Reason
X`09----`09`09`09------
X`09JLG_CANT_QUEUE`09`09can't queue read to TT
X`09JLG_CANT_WRITE`09`09can't write to FT
X`09status
X
X****************************************************************************
V****
X****************************************************************************
V***/
X
Xstatic void log_session(USHORT ft_chan,USHORT tt_chan)
X
X`7B`09/*** log_session ***/
X`09`09`09`09`09/********   LOCAL  VARIABLES   ********/
X`09 ULONG`09  status;`09`09/* return code status holder`09      */
X`09 USHORT   length;
Xstatic`09 char`09  log_enable`5B`5D = `7B"Logging has been ENABLED\r\n"`7D,
X`09`09  log_disable`5B`5D = `7B"Logging has been DISABLED\r\n"`7D,
X`09`09  stamp_enable`5B`5D = `7B"Time stamping has been ENABLED\r\n"`7D,
X`09`09  stamp_disable`5B`5D = `7B"Time stamping has been DISABLED\r\n"`7D;
X
X
X   cr_buf->status = 0;
X   cr_buf->count = 1;
X   cr_buf->data`5B0`5D = 015;
X
X   /* start reading from the FT device */
X
X   status = PTD$READ(ft_efn,ft_chan,&ft_ast,0,&(ft_buf->status),FT_DATA_MAX)
V;
X`09`09   `20
X   if(!(status & SS$_NORMAL))
X   `7B
X      kill_log();
X      mess_d.dsc$a_pointer = "read on FT device (in log_session())";
X      mess_d.dsc$w_length = (USHORT) strlen(mess_d.dsc$a_pointer);
X      LIB$SIGNAL(JLG_CANT_QUEUE,1L,&mess_d);
X      LIB$STOP(status);
X   `7D
X
X   /* wait for the event flag to be set; this is important but I can't
X    * take credit for it; from the README file for PHOTO:
X    *
X    *     PHOTO running on a multi-processor VAX (e.g.  VAX 8800) with
X    * VAX/VMS Version 5.x runs into a problem due to SMP which allows the
X    * subprocess to get MUCH more CPU time then was previously possible
X    * without SMP.  The subprocess generates hangups very rapidly and on a
X    * lightly loaded system it will generate a hangup between the time
X    * "enable_hangups" is turned on and when begin_session posts a
X    * QIOW(IO$_READVBLK) on py_chan.  This causes PHOTO to exit as if the
X    * subprocess had logged out!
X    *`20
X    *      PHOTO has been fixed to issue a QIO instead of QIOW followed by
X    * WAITFR and "enable_hangups" is now turned on after the first QIO to
X    * py_chan in begin_session (used to be turned on in main).  It has been
X    * tested on a VAX 8800 with VAX/VMS Version 5.0-2.
X    *`20
X    * `09Michael Kimura`09`09Internet: mnk%draco@hac2arpa.hac.com
X    * `09Hughes Aircraft Co.`09BITnet:   mnk@draco.hac.com
X    *`20
X    * `09January 31, 1989
X    */
X
X   status = SYS$WAITFR(ft_efn);
X
X   if(!(status & SS$_NORMAL))
X   `7B
X      kill_log();
X      LIB$STOP(status);
X   `7D
X
X   flags.hangups = TRUE;`09`09/* enable hangups on the FT device    */
X
X   for(;;)
X   `7B
X      /* read from the TTY */
X
X      status = SYS$QIOW(tt_r_efn,tt_chan,IO$_READVBLK,&tt_read_iosb,0,0,
X`09`09`09tt_buf->data,1,0,&term_block,0,0);
X
X      if(!(status & SS$_NORMAL) `7C`7C !(tt_read_iosb.status & SS$_NORMAL))
X      `7B
X`09 kill_log();
X`09 mess_d.dsc$a_pointer = "read on TT device";
X`09 mess_d.dsc$w_length = (USHORT) strlen(mess_d.dsc$a_pointer);
X`09 LIB$STOP(JLG_CANT_QUEUE,1L,&mess_d);
X      `7D
X
X      /* Stall for 50 milli-seconds waiting for more data */
X
X      status = SYS$SETIMR(wait_efn,&bintim,0,0);
X
X      if(!(status & SS$_NORMAL))
X      `7B
X`09 kill_log();
X`09 LIB$STOP(status);
X      `7D
X
X      status = SYS$WAITFR(wait_efn);
X
X      if(!(status & SS$_NORMAL))
X      `7B
X`09 kill_log();
X`09 LIB$STOP(status);
X      `7D
X
X      /* get the rest of it */
X
X      status = SYS$QIOW(tt_r_efn,tt_chan,IO$_READVBLK`7CIO$M_TIMED,&tt_read_
Viosb,
X`09`09`090,0,&(tt_buf->data`5B1`5D),TT_DATA_MAX - 1,0,&term_block,
X`09`09`090,0);
X
X      if(!(status & SS$_NORMAL))
X`09 LIB$STOP(status);
X
X      if(tt_buf->data`5B0`5D == CARRIAGE_RETURN && flags.time_stamp)
X      `7B
X`09 flags.command = TRUE;`09`09/* this was a command`09`09      */
X`09 get_stamp(stamp_buf);`09`09/* create the time stamp for later    */
X      `7D
X      else
X      `7B
X`09 /* check for toggle characters */
X
X`09 if(tt_buf->data`5B0`5D == TOGGLE_LOG)
X`09 `7B
X`09    /* toggle the logging to the file */
X
X`09    if(flags.logging)
X`09       write_tt(tt_chan,log_disable,(ULONG) sizeof(log_disable) - 1);
X`09    else
X`09       write_tt(tt_chan,log_enable,(ULONG) sizeof(log_enable) - 1);
X                                                `20
X`09    write_ft(ft_chan,cr_buf);
X`09    flags.logging = !flags.logging;
X`09    flags.verify = FALSE;
X`09 `7D
X`09 else if(tt_buf->data`5B0`5D == TOGGLE_STAMP)
X`09 `7B
X`09    /* toggle time-stamping */
X
X`09    if(flags.time_stamp)
X`09       write_tt(tt_chan,stamp_disable,
X`09`09`09(ULONG) sizeof(stamp_disable) - 1);
X`09    else
X`09      write_tt(tt_chan,stamp_enable,(ULONG) sizeof(stamp_enable) - 1);
X
X`09    write_ft(ft_chan,cr_buf);
X`09    flags.time_stamp = !flags.time_stamp;
X`09 `7D
X      `7D
X
X      /* write it to the FT device */
X
X      tt_buf->count = tt_read_iosb.count + 1;
X
X      status = write_ft(ft_chan,tt_buf);
X
X      if(!(status & SS$_NORMAL))
X      `7B
X         kill_log();
X         LIB$STOP(JLG_CANT_WRITE,1L,"to FT device");
X      `7D
X   `7D
X
X   return;`09`09`09`09/* should never get here`09      */
X
X`7D`09/*** log_session ***/
X`0C
X/***************************************************************************
V****
X****************************************************************************
V****
X
X  Function:`09ask_disposition
X
X  Purpose:`09Ask the user what should be done with the log file and do
X`09`09it.
X
X  Formal Parameters:
X
X`09Name`09`09`09Description
X`09----`09`09`09-----------
X`09filename`09`09name of log file
X`09stage_dir`09`09staging directory for log files
X`09flags`09`09`09computed flags
X`09args`09`09`09run-time arguments
X
X  Global variables:
X
X`09Name`09`09`09Examine/Modify/Use/Read/Write
X`09----`09`09`09-----------------------------
X`09disp_failed`09`09`09  X
X`09tt_chan`09`09`09`09`09X
X`09LIB$M_CLI_CTRLY`09`09`09`09X
X
X  Return Codes:
X
X`09Code `09 `09`09Reason
X`09----`09`09`09------
X`09none
X
X  Termination Codes:
X
X`09Code`09`09`09Reason
X`09----`09`09`09------
X`09status
X
X****************************************************************************
V****
X****************************************************************************
V***/
X
Xstatic void ask_disposition(char *logfile,char *stage_dir,FLAG_DEF *flags,
X`09`09`09    ARG_DEF *args)
X
X`7B`09/*** ask_disposition ***/
X`09`09`09`09`09/********   LOCAL  VARIABLES   ********/
X`09 ULONG`09  status,`09`09/* return code status holder`09      */
X`09`09  disable_mask;`09`09/* for disabling control-Y at DCL     */
X`09 char`09  *save_ptr;`09`09/* saved logfile name`09`09      */
X`09 USHORT`09  done,`09`09`09/* loop control variable`09      */
X`09`09  length;`09`09/* length of read from my_gets`09      */
X`09 char`09  ch`5B10`5D;`09`09/* character read in`09`09      */
Xstatic $DESCRIPTOR(in_d,"SYS$INPUT");`09/* input channel descriptor`09
V      */
X
X
X   disable_mask = LIB$M_CLI_CTRLY;`09/* tell DCL to ignore control-Y`09
V      */
X
X   status = LIB$DISABLE_CTRL(&disable_mask);
X
X   if(!(status & SS$_NORMAL))
X   `7B
X      delete_log(logfile);
X      LIB$SIGNAL(status);
X   `7D
X
X   if(flags->verify)
X      my_puts("\n\nYour log file is VERIFIED.");
X   else
X      my_puts("\n\nYour log file is UNVERIFIED.");
X
X   done = FALSE;
X   status = SUCCESS;`09`09`09/* just to be sure`09`09      */
X
X   do
X   `7B
X      if(args->print)
X`09 ch`5B0`5D = 'P';`09`09`09/* user specified /PRINT`09      */
X      else if(args->mail)
X`09 ch`5B0`5D = 'M';
X      else if(args->save)
X`09 ch`5B0`5D = 'S';
X      else
X      `7B
X`09 my_puts("\n\nDo you want to:");
X`09 my_puts("  Print your log file?                  Enter p");
X`09 my_puts("  Save log to your area?                Enter s");
X`09 my_puts("  Mail notification of log to someone?  Enter m");
X`09 my_puts("  Delete your log file?                 Enter d\n");
X`09 status = my_gets(tt_chan,&ch,"     Your choice `5Bdefault is d`5D ? ",
X`09`09`09  &length,sizeof(ch) - 1);
X`09 squeeze_str(ch);
X
X`09 if(status == CANCEL)
X`09    ch`5B0`5D = 'D';`09`09/* `5EC or `5EY`09`09`09      */
X`09 else if(ch`5B0`5D == CARRIAGE_RETURN `7C`7C ch`5B0`5D == '\0')
X`09    ch`5B0`5D = 'D'; `09`09/* default is delete`09`09      */
X`09 else if((status == SUCCESS && ch`5B1`5D != '\0') `7C`7C status == FAILUR
VE)
X`09    ch`5B0`5D = '\0';`09`09/* more than one char; error`09      */
X`09 else
X`09    ch`5B0`5D = _toupper(ch`5B0`5D);
X      `7D
X
X      switch(ch`5B0`5D)
X      `7B
X`09 case('P'):
X
X`09    /* user wants it printed */
X
X`09    status = print_log(logfile,tt_chan,flags->verify);
X
X`09    if(status == FAILURE)
X`09    `7B
X`09       my_puts("\n\7*ERROR* Cannot print log file");
X`09       args->print = FALSE;`09/* start over`09`09`09      */
X`09       disp_failed = TRUE;`09/* ensure user is prompted next time  */
X`09    `7D
X`09    else if(status == CANCEL)
X`09    `7B
X`09       /* user entered `5EC or `5EY; delete the log file and get out */
X
X`09       delete_log(logfile);
X`09       my_puts("\nLog file deleted.\n");
X`09       done = TRUE;
X`09    `7D
X            else
X`09    `7B
X`09       done = TRUE;`09`09/* no need to delete log file here    */
X`09    `7D
X
X`09    break;
X
X`09 case('S'):
X
X`09    status = save_log(logfile,tt_chan);
X
X`09    if(status == FAILURE)
X`09    `7B
X`09       my_puts("\n\7*ERROR* Cannot save log file");
X`09       args->save = FALSE;`09/* start over`09`09`09      */
X`09       disp_failed = TRUE;`09/* ensure user is prompted next time  */
X`09    `7D
X`09    else if(status == CANCEL)
X`09    `7B
X`09       /* user entered `5EC or `5EY; delete the log file and get out */
X
X`09       delete_log(logfile);
X`09       my_puts("\nLog file deleted.\n");
X`09       done = TRUE;
X`09    `7D
X`09    else
X`09    `7B
X`09       done = TRUE;
X`09       delete_log(logfile);
X`09    `7D
X
X`09    break;
X
X`09 case('D'):
X
X`09    /* we really don't care too much if delete() fails since
X`09     * the batch job will kill it anyway; besides, it should never
X`09     * fail
X`09     */
X
X`09    delete_log(logfile);
X`09    my_puts("\nLog file deleted.\n");
X`09    done = TRUE;
X
X`09    break;
X
X`09 case('M'):
X
X`09    status = mail_log(logfile,stage_dir,tt_chan,flags->verify);
X
X`09    if(status == FAILURE `7C`7C status == NO_INPUT)
X`09    `7B
X`09       args->mail = FALSE;
X`09       disp_failed = TRUE;`09/* ensure user is prompted next time  */
X`09    `7D
X`09    else if(status == CANCEL)
X`09    `7B
X`09       /* user entered `5EC or `5EY; delete the log file and get out */
X
X`09       delete_log(logfile);
X`09       my_puts("\nLog file deleted.\n");
X`09       done = TRUE;
X`09    `7D
X`09    else if(status == SUCCESS)
X`09    `7B
X`09       done = TRUE;
X`09       delete_log(logfile);
X`09    `7D
X
X`09    break;
X
X`09 default:
X
X`09    /* bad option specified; try again */
X
X`09    my_puts("\n\7Invalid option.  Try again.");
X`09    break;
X      `7D
X   `7D
X   while(!done);
X
X   status = LIB$ENABLE_CTRL(&disable_mask);
X
X   if(!(status & SS$_NORMAL))
X      LIB$STOP(status);
X
X   return;
X
X`7D`09/*** ask_disposition ***/
X`0C
X/***************************************************************************
V****
X****************************************************************************
V****
X
X  Function:`09get_file
X
X  Purpose:`09Create a filename and open the log file.
X
X  Formal Parameters:
X
X`09Name`09`09`09Description
X`09----`09`09`09-----------
X`09filename`09`09name of log file
X`09log_dir`09`09`09directory where log files live
X`09log_fab`09`09`09FAB for log file
X`09log_rab`09`09`09RAB for log file
X`09log_xabpro`09`09XABPRO for log file
X`09args`09`09`09command-line arguments
X`09flags`09`09`09program flags
X
X  Global variables:
X
X`09Name`09`09`09Examine/Modify/Use/Read/Write
X`09----`09`09`09-----------------------------
X`09privs`09`09`09`09  X`09X
X
X  Return Codes:
X
X`09Code`09 `09`09Reason
X`09----`09`09`09------
X`09none
X
X  Termination Codes:
X
X`09Code`09`09`09Reason
X`09----`09`09`09------
X`09status`09`09`09return code from system calls
X
X****************************************************************************
V****
X****************************************************************************
V***/
X
Xstatic ULONG get_file(char *filename,char *log_dir,struct FAB *log_fab,
X`09`09      struct RAB *log_rab,struct XABPRO *log_xabpro,
X`09`09      ARG_DEF *args,FLAG_DEF *flags)
X
X`7B`09/*** get_file ***/
X`09`09`09`09`09/********   LOCAL  VARIABLES   ********/
X`09 ULONG`09  status;`09`09/* return code status holder`09      */
X
X
X#ifdef PHOTO_MODE
X
X   strcpy(filename,"JOBLOG.LOG");
X
X#else
X
X   /* turn on SYSPRV so we can create the log file */
X
X   privs.prv$v_sysprv = ON;
X
X   status = SYS$SETPRV(ON,&privs,FALSE,NULL);
X
X   if(!(status & SS$_NORMAL))
X      return(status);
X
X   strcpy(filename,"JOBXXXXXX");`09/* make our own log file name`09      */
X
X   if(mktemp(filename) == NULL)
X   `7B
X      my_puts("JOBLOG -- cannot create log file name\n");
X      SYS$EXIT();
X   `7D
X
X   strcat(filename,".LOG");
X   strcpy(flags->filename,filename);`09/* save filename for later`09      */
X   strins(filename,log_dir,0);`09`09/* add secure directory name`09      */
X
X#endif
X
X   *log_fab = cc$rms_fab;
X   *log_rab = cc$rms_rab;
X   *log_xabpro = cc$rms_xabpro;
X
X   /* if we were doing exact logging, we would have a test here for it and
X    * we would open the log file appropriately; since exact logging is such
X    * a pain in the a*s, we'll just assume everything is "unexact" (is that
X    * even a word?)
X    */
X
X   log_fab->fab$l_fna = filename;`09/* name of log file`09`09      */
X   log_fab->fab$b_fns = (UCHAR) strlen(filename);
X   log_fab->fab$l_fop = FAB$M_SUP;`09/* supersede old version of log file  *
V/
X   log_fab->fab$l_fop = FAB$M_MXV;`09/* supersede old version of log file  *
V/
X   log_fab->fab$b_org = FAB$C_SEQ;`09/* sequential access`09`09      */
X   log_fab->fab$b_rat = FAB$M_CR;`09/* CR attributes for records`09      */
X   log_fab->fab$b_rfm = FAB$C_VAR;`09/* variable-length records`09      */
X   log_fab->fab$b_shr = FAB$M_NIL;`09/* don't allow sharing`09`09      */
X   log_fab->fab$l_xab = log_xabpro;`09/* for setting protection on close
V    */
X
X   log_rab->rab$l_fab = log_fab;`09/* FAB for log file`09`09      */
X   log_rab->rab$b_rac = RAB$C_SEQ;`09/* sequential access`09`09      */
X   log_rab->rab$l_rop = RAB$M_WBH;
X
X   /* set the protection to override any default the user might've set */
X
X   log_xabpro->xab$w_pro = ((XAB$M_NOREAD `7C XAB$M_NOWRITE `7C XAB$M_NOEXE
V `7C
X`09`09`09    XAB$M_NODEL) << XAB$V_GRP) `7C ((XAB$M_NOREAD `7C
X`09`09`09    XAB$M_NOWRITE `7C XAB$M_NOEXE `7C XAB$M_NODEL)
X`09`09`09    << XAB$V_WLD);
X
X   status = SYS$CREATE(log_fab);
X
X   if(!(status & RMS$_NORMAL))
X      return(status);
X
X   status = SYS$CONNECT(log_rab);
X
X   if(!(status & RMS$_NORMAL))
X   `7B
X      kill_log();
X      return(status);
X   `7D
X
X#ifndef PHOTO_MODE
X
X   /* now that the file is open, turn SYSPRV off again to be safe */
X
X   status = SYS$SETPRV(OFF,&privs,FALSE,NULL);
X
X   if(!(status & SS$_NORMAL))
X      return(status);
X
X   privs.prv$v_sysprv = OFF;
X
X#endif
X
X   return(RMS$_NORMAL);
X
+-+-+-+-+-+-+-+-  END  OF PART 3 +-+-+-+-+-+-+-+-
