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

-+-+-+-+-+-+-+-+ START OF PART 4 -+-+-+-+-+-+-+-+
X`7D`09/*** get_file ***/
X`0C
X/***************************************************************************
V****
X****************************************************************************
V****
X
X  Function:`09welcome
X
X  Purpose:`09Write the welcome message to the tty.
X
X  Formal Parameters:
X
X`09Name`09`09`09Description
X`09----`09`09`09-----------
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`09none
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 void welcome(ARG_DEF *args)
X
X`7B`09/*** welcome ***/
X`09`09`09`09`09/********   LOCAL  VARIABLES   ********/
X`09 USHORT`09  i = 0;`09`09/* array index`09`09`09      */
Xstatic`09 char`09  *text`5B`5D = `7B`09`09/* stuff to say upon entry to JOBL
VOG  */
X`7B" "`7D,
X`7B"Welcome to JOBLOG!  Please try not to use full-screen editors or other"`
V7D,
X`7B"screen-oriented programs as they tend not to be logged correctly."`7D,
X`7B" "`7D,
X`7B"Also, please don't use SET HOST as it causes problems with JOBLOG log"`7
VD,
X`7B"files."`7D,
X`7B" "`7D,
X`7B"To exit JOBLOG, enter LOGOUT."`7D,
X`7B" "`7D,
X`7B""`7D`7D;      `20
X
X
X#ifndef PHOTO_MODE
X
X   if(!args->expert)
X      while(*text`5Bi`5D != '\0')
X`09 my_puts(text`5Bi++`5D);
X
X#endif
X
X   my_puts("\nJOBLOG started.\n");`09`09/* mandatory startup message`09
V      */
X   return;
X
X`7D`09/*** welcome ***/
X`0C
X/***************************************************************************
V****
X****************************************************************************
V****
X
X  Function:`09copy_file
X
X  Purpose:`09Make a copy of a file.
X
X  Formal Parameters:
X
X`09Name`09`09`09Description
X`09----`09`09`09-----------
X`09source`09`09`09file to be copied
X`09dest`09`09`09where copy is to go
X`09priv_flag`09`09TRUE if copying to staging area
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`09SUCCESS
X`09FAILURE
X
X****************************************************************************
V****
X****************************************************************************
V***/
X
Xstatic ULONG copy_file(char *source,char *dest,USHORT priv_flag)
X
X`7B`09/*** copy_file ***/
X`09`09`09`09`09/********   LOCAL  VARIABLES   ********/
X`09 ULONG`09  status,`09`09/* return code status holder`09      */
X`09`09  status2,`09`09/* some secondary return codes`09      */
X`09`09  status3,
X`09`09  status4;
X`09 char  `09  in_buf`5BIN_BUF_MAX+1`5D;`09/* buffer for reading/writing`09
V      */
Xstruct`09 FAB`09  in_fab,`09`09/* FAB's for input and output files   */
X`09`09  out_fab;
Xstruct`09 RAB`09  in_rab,`09`09/* RAB's for input and output files   */
X`09`09  out_rab;
X
X
X   in_fab = cc$rms_fab;  `09`09/* initialize all of the RMS blocks   */
X   in_rab = cc$rms_rab;
X   out_rab = cc$rms_rab;
X
X   in_fab.fab$b_fac = FAB$M_BIO `7C`09/* block I/O for input file`09      */
X`09`09      FAB$M_GET;
X            `20
X   in_fab.fab$l_fna = source;
X   in_fab.fab$b_fns = (UCHAR) strlen(source);
X   in_fab.fab$b_fac = FAB$M_BIO `7C FAB$M_GET;
X
X   in_rab.rab$l_fab = &in_fab;`09`09/* pointer to input FAB`09`09      */
X   in_rab.rab$b_rac = RAB$C_SEQ;`09/* sequential access for copy`09      */
X   in_rab.rab$w_usz = IN_BUF_MAX;`09/* length of input buffer`09      */
X   in_rab.rab$l_ubf = in_buf;`09`09/* pointer to buffer`09`09      */
X
X   out_rab.rab$l_fab = &out_fab;`09/* pointer to input FAB`09`09      */
X   out_rab.rab$b_rac = RAB$C_SEQ;`09/* sequential access for copy`09      */
X   out_rab.rab$w_usz = IN_BUF_MAX; `09/* length of output buffer`09      */
X   out_rab.rab$l_rbf = in_buf; `09`09/* pointer to buffer`09`09      */
X
X   privs.prv$v_sysprv = ON;`09`09/* need SYSPRV to open logfile`09      */
X
X   status = SYS$SETPRV(ON,&privs,FALSE,NULL);
X
X   if(!(status & SS$_NORMAL))
X      return(FAILURE);
X
X   /* open the input file */
X
X   status = SYS$OPEN(&in_fab);
X
X   if(!(status & RMS$_NORMAL))
X   `7B
X      SYS$CLOSE(&in_fab);
X      return(FAILURE);
X   `7D
X
X   /* connect the input file's RMS blocks */
X
X   status = SYS$CONNECT(&in_rab);
X
X   if(!(status & RMS$_NORMAL))
X   `7B
X      SYS$CLOSE(&in_fab);
X      return(FAILURE);
X   `7D
X
X   out_fab = in_fab;  `09`09`09/* copy the input file's FAB`09      */
X   out_fab.fab$w_ifi = 0; `09`09/* reset this!`09`09`09      */
X   out_fab.fab$b_fac = FAB$M_BIO `7C FAB$M_PUT;
X
X   out_fab.fab$l_fna = dest;
X   out_fab.fab$b_fns = (UCHAR) strlen(dest);
X
X
X   if(priv_flag == FALSE)`09`09/* copying to staging area?`09      */
X   `7B
X      /* copying to user's area; turn off SYSPRV *BEFORE* opening the
X       * destination file
X       */
X
X      status = SYS$SETPRV(OFF,&privs,FALSE,NULL);
X
X      if(!(status & SS$_NORMAL))
X`09 return(FAILURE);
X
X      privs.prv$v_sysprv = OFF;
X   `7D
X
X   /* open the output file */
X
X   status = SYS$CREATE(&out_fab);
X
X   if(!(status & RMS$_NORMAL))
X   `7B
X      SYS$CLOSE(&out_fab);
X      SYS$CLOSE(&in_fab);`20
X      return(FAILURE);
X   `7D
X
X   /* connect the output file's RMS blocks */
X
X   status = SYS$CONNECT(&out_rab);
X
X   if(!(status & RMS$_NORMAL))
X   `7B
X      SYS$CLOSE(&out_fab);
X      SYS$CLOSE(&in_fab);
X      return(FAILURE);
X   `7D
X
X   if(priv_flag == TRUE)`09`09/* privs still on?`09`09      */
X   `7B
X      /* SYSPRV was left on so that the destination file (which is in the
X       * staging area) could be created; turn it off
X       */
X
X      status = SYS$SETPRV(OFF,&privs,FALSE,NULL);
X
X      if(!(status & SS$_NORMAL))
X`09 return(FAILURE);
X
X      privs.prv$v_sysprv = OFF;
X   `7D
X
X   /* now copy the input file to the output file */
X
X   status = SYS$READ(&in_rab);
X   status2 = RMS$_NORMAL;`09`09/* have to lie to fool the loop`09      */
X
X   while((status == RMS$_NORMAL) && (status2 == RMS$_NORMAL))
X   `7B
X      out_rab.rab$w_rsz = in_rab.rab$w_rsz;
X      status2 = SYS$WRITE(&out_rab);
X      status = SYS$READ(&in_rab);
X   `7D
X
X   /* close both of the files */
X
X   status3 = SYS$CLOSE(&in_fab);
X   status4 = SYS$CLOSE(&out_fab);
X
X   /* did the loop terminate properly? if not, delete the output file and
X    * scream at the user
X    */
X
X   if(status != RMS$_EOF `7C`7C status2 != RMS$_NORMAL `7C`7C status3 != RMS
V$_NORMAL `7C`7C
X      status4 != RMS$_NORMAL)
X      return(FAILURE);
X
X   return(SUCCESS);
X
X`7D`09/*** copy_file ***/
X`0C
X/***************************************************************************
V****
X****************************************************************************
V****
X
X  Function:`09print_log
X
X  Purpose:`09Print the log file (verified or nonverified) to the line
X`09`09printer.  The /DELETE qualifier is passed to the print job
X`09`09so that the log file is deleted after printing.
X
X  Formal Parameters:
X
X`09Name`09`09`09Description
X`09----`09`09`09-----------
X`09logfile`09`09`09name of log file
X`09channel`09`09`09TTY channel
X`09verify_flag`09`09TRUE = verified LPT copy
X
X  Global variables:
X
X`09Name`09`09`09Examine/Modify/Use/Read/Write
X`09----`09`09`09-----------------------------
X`09disp_failed`09`09   X
X`09privs`09`09`09`09  X`09X
X
X  Return Codes:
X
X`09Code`09 `09`09Reason
X`09----`09`09`09------
X`09SUCCESS
X`09FAILURE
X`09CANCEL
X
X****************************************************************************
V****
X****************************************************************************
V***/
X
Xstatic ULONG print_log(char *logfile,USHORT channel,UCHAR verify_flag)
X
X`7B`09/*** print_log ***/
X   `09`09`09`09`09/********   LOCAL  VARIABLES   ********/
X`09 ULONG`09  status,`09`09/* return code status holder`09      */
X`09`09  status2;`09`09/* another return code holder`09      */
X`09 long`09  entry_num;`09`09/* entry number in queue`09      */
X`09 USHORT`09  length;`09`09/* length of status string`09      */
X`09 IOSB_DEF iosb;`09`09`09/* I/O status block`09`09      */
X`09 char`09  def_queue`5BQUEUE_MAX+1`5D,
X`09`09  queue`5BQUEUE_MAX+1`5D,`09/* queue to use for call`09      */
X`09`09  prompt`5BBUFSIZ`5D,
X`09`09  status_str`5BSTATUS_STR_MAX+1`5D;
X`09 $DESCRIPTOR(print_d,"PRINT");
X`09 $DESCRIPTOR(table_d,"LNM$PROCESS");
X`09 $DESCRIPTOR(table2_d,"LNM$SYSTEM");
X`09 $DESCRIPTOR(queue_d,queue);
X`09 $DESCRIPTOR(sys_print_d,"SYS$PRINT");
Xstatic`09 char`09  *account = "VERIFY",
X`09`09  *account2 = "UNVERIFY",
X`09`09  *job_name = "VERIFIED_JOBLOG",
X`09`09  *job_name2 = "UNVERIFIED_JOBLOG",
X`09`09  *verified = "Verified JOBLOG listing",
X`09`09  *unverified = "Unverified JOBLOG listing";
Xstatic`09 ITM_LST  items`5B`5D = `7B`09`09/* item list for stuff we want to
V do  */
X`7B0,SJC$_ACCOUNT_NAME,0L,0L`7D,
X`7B0,SJC$_FILE_SPECIFICATION,0L,0L`7D,
X`7B0,SJC$_DELETE_FILE,0L,0L`7D,
X`7B0,SJC$_ENTRY_NUMBER_OUTPUT,0L,0L`7D,
X`7B0,SJC$_JOB_NAME,0L,0L`7D,
X`7B0,SJC$_JOB_STATUS_OUTPUT,0L,0L`7D,
X`7B0,SJC$_NOTE,0L,0L`7D,
X`7B0,SJC$_NOTIFY,0L,0L`7D,
X`7B0,SJC$_QUEUE,0L,0L`7D,
X`7B0,0,0L,0L`7D`7D,
X`09`09  items2`5B`5D = `7B`09`09/* items obtained during translation  */
X`7B0,LNM$_STRING,NULL,NULL`7D,`09`09/* things are filled in below`09      */
X`7B0,0,NULL,NULL`7D`7D;
X
X  `20
X   status = CLI$GET_VALUE(&print_d,&queue_d,&length);
X
X   if(status == SS$_NORMAL && !disp_failed)
X      queue`5Blength`5D = '\0';`09`09/* use it`09`09`09      */
X   else
X   `7B
X      /* get the current default print queue from SYS$PRINT */
X
X      items2`5B0`5D.buf_addr = def_queue;
X      items2`5B0`5D.ret_len = &length;
X      items2`5B0`5D.buf_len = sizeof(def_queue);
X      length = 0;
X
X      /* check the user's process table first */
X
X      status = SYS$TRNLNM(0L,&table_d,&sys_print_d,0,&items2);
X
X      if(status != SS$_NORMAL `7C`7C length == 0)
X      `7B
X`09 status = SYS$TRNLNM(0L,&table2_d,&sys_print_d,0,&items2);
X
X`09 if(status != SS$_NORMAL `7C`7C length == 0)
X`09 `7B
X`09    my_puts("\n\7*ERROR* SYS$PRINT not defined.\n");
X`09    return(FAILURE);
X`09 `7D
X      `7D
X
X      my_puts(" ");
X
X      def_queue`5Blength`5D = '\0';`09`09/* make it a string`09`09      */
X      cat(prompt,"Which printer did you want to use `5Bdefault is ",def_queu
Ve,
X`09  "`5D? ");
X
X      status = my_gets(channel,queue,prompt,&length,sizeof(queue) - 1);
X
X      if(status == FAILURE)
X`09 return(FAILURE);
X      else if(status == CANCEL)
X`09 return(CANCEL);
X
X      /* input is ok if we get here */
X
X      queue`5Blength`5D = '\0';
X      str_pref_trim(queue);
X      str_post_trim(queue);
X
X      if(queue`5B0`5D == '\0')
X`09 strcpy(queue,def_queue);`09/* use the default`09`09      */
X   `7D
X
X   /* set up the item list so we can print */
X
X   items`5B1`5D.buf_len = strlen(logfile);
X   items`5B1`5D.buf_addr = logfile;
X   items`5B3`5D.buf_len = sizeof(long);
X   items`5B3`5D.buf_addr = &entry_num;
X   items`5B5`5D.buf_len = STATUS_STR_MAX;
X   items`5B5`5D.buf_addr = status_str;
X   items`5B5`5D.ret_len = &length;
X   items`5B8`5D.buf_len = strlen(queue);
X   items`5B8`5D.buf_addr = queue;
X
X   if(verify_flag)
X   `7B
X      items`5B0`5D.buf_len = strlen(account);
X      items`5B0`5D.buf_addr = account;
X      items`5B4`5D.buf_len = strlen(job_name);
X      items`5B4`5D.buf_addr = job_name;
X      items`5B6`5D.buf_len = strlen(verified);
X      items`5B6`5D.buf_addr = verified;
X   `7D
X   else
X   `7B
X      items`5B0`5D.buf_len = strlen(account2);
X      items`5B0`5D.buf_addr = account2;
X      items`5B4`5D.buf_len = strlen(job_name2);
X      items`5B4`5D.buf_addr = job_name2;
X      items`5B6`5D.buf_len = strlen(unverified);
X      items`5B6`5D.buf_addr = unverified;
X   `7D
X
X   privs.prv$v_cmkrnl = ON;`09`09/* need CMKRNL to change job name     */
X   privs.prv$v_sysprv = ON;`09`09/* need SYSPRV to read access log     */
X
X   status2 = SYS$SETPRV(ON,&privs,FALSE,NULL);
X
X   if(!(status2 & SS$_NORMAL))
X   `7B
X      LIB$SIGNAL(status2);
X      return;
X   `7D
X   /* now try to queue the log file to the printer */
X
X   status = SYS$SNDJBCW(0,SJC$_ENTER_FILE,0L,&items,&iosb,0L,0L);
X
X   /* turn off CMKRNL and SYSPRV *NOW* before checking if SYS$SNDJBCW()
X    * worked
X    */
X
X   status2 = SYS$SETPRV(OFF,&privs,FALSE,NULL);
X
X   if(!(status2 & SS$_NORMAL))
X   `7B
X      LIB$SIGNAL(status2);
X      return;
X   `7D
X
X   /* now see if SYS$SNDJBCW() worked */
X
X   if(!(status & SS$_NORMAL))
X      return(FAILURE);
X
X   if(iosb.status != SS$_NORMAL)
X   `7B
X      LIB$SIGNAL(iosb.status);
X      return(FAILURE);
X   `7D
X
X   /* report the status line to the user */
X
X   status_str`5Blength`5D = '\0';`09`09/* make status message a string`09
V      */
X   my_puts(" ");
X   my_puts(status_str);
X
X   return(SUCCESS);
X
X`7D`09/*** print_log ***/
X`0C
X/***************************************************************************
V****
X****************************************************************************
V****
X
X  Function:`09mail_log
X
X  Purpose:`09Mail notification of a verified JOBLOG to the specified user
X`09`09and copy the log file to JOBLOG staging area.
X
X  Formal Parameters:
X
X`09Name`09`09`09Description
X`09----`09`09`09-----------
X`09logfile`09`09`09name of log file
X`09stage_dir`09`09staging directory for log files
X`09channel`09`09`09TTY channel
X`09verify`09`09`09TRUE if JOBLOG still verified
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`09privs`09`09`09`09   X    X
X`09JLG_NO_SPAWN`09`09`09`09X
X
X  Return Codes:
X
X`09Code`09 `09`09Reason
X`09----`09`09`09------
X`09SUCCESS
X`09FAILURE
X`09NO_INPUT
X
X****************************************************************************
V****
X****************************************************************************
V***/
X
Xstatic ULONG mail_log(char *logfile,char *stage_dir,USHORT channel,UCHAR ver
Vify)
X
X`7B`09/*** mail_log ***/
X`09`09`09`09`09/********   LOCAL  VARIABLES   ********/
X`09 char`09  *username,`09`09/* name of user mailing the notice    */
X`09`09  *verify_ptr,`09`09/* used for making mail message`09      */
X`09`09  *verify_ch;`09`09/* used for making filename`09      */
X`09 ULONG`09  status,`09`09/* return code status holder`09      */
X`09`09  status2;`09`09/* secondary return code holder`09      */
X`09 long`09  item_code;`09`09/* for LIB$GETJPI()'s sake`09      */
X`09 USHORT`09  length;`09`09/* length of string from LIB$GETJPI() */
X`09 time_t`09  time_val;`09`09/* value from time()`09`09      */
X`09 IOSB_DEF iosb;`09`09`09/* for QIO's`09`09`09      */
X`09 char`09  tempfile`5BNAM$C_MAXRSS+1`5D,
X`09`09  filename`5BNAM$C_MAXRSS+1`5D,
X`09`09  out_buf`5BBUFSIZ`5D,`09/* formatting and I/O buffer`09      */
X`09`09  account`5BACCOUNT_MAX+1`5D,
X`09`09  recipient`5BUSERNAME_MAX+1`5D,
X`09`09  command`5BCOMMAND_MAX+1`5D,
X`09`09  prompt`5B`5D =
X`09`09  `7B"Who do you want to mail the log file notification to? "`7D;
Xstruct`09 tm`09  *time_ptr;`09`09/* pointer to localtime() structure   */
Xstruct`09 FAB`09  out_fab;`09`09/* for creating mail message file     */
Xstruct`09 RAB`09  out_rab;
X$DESCRIPTOR(null_d,"NL:");
X$DESCRIPTOR(account_d,account);
X$DESCRIPTOR(command_d,command);
X$DESCRIPTOR(filename_d,filename);
X$DESCRIPTOR(recipient_d,recipient);
X$DESCRIPTOR(mail_d,"MAIL");
X$DESCRIPTOR(ctrstr_d,
X`09 "!AD!AD_!AD_!AD.!AD_JOBLOG_!ZL!ZL_!ZL!ZL_!ZL!ZL_!ZL!ZL_!ZL!ZL_!ZL!ZL");
X
X
X   status = CLI$GET_VALUE(&mail_d,&recipient_d,&length);
X
X   if(status == SS$_NORMAL && !disp_failed)
X   `7B
X      /* save the /MAIL recipient */
X
X      recipient`5Blength`5D = '\0';`09`09/* make it a string`09`09      */
X   `7D
X   else
X   `7B
X      /* /USER wasn't specified; prompt the user for it */
X
X      my_puts(" ");
X      status = my_gets(channel,recipient,prompt,&length,sizeof(recipient) -
V 1);
X
X      if(status == FAILURE)
X`09 return(FAILURE);
X      else if(status == CANCEL)
X`09 return(CANCEL);
X
X      /* input is ok if we get here */
X
X      str_pref_trim(recipient);
X      str_post_trim(recipient);
X
X      if(recipient`5B0`5D == '\0')
X      `7B
X`09 my_puts("\n\07You must specify a username.");
X`09 return(NO_INPUT);
X      `7D
X
X      strlu(recipient);`09`09`09/* conver to all uppercase`09      */
X   `7D
X
X   /* see if we have a valid recipient */
X
X   if(valid_recip(recipient) == FALSE)
X   `7B
X      cat(out_buf,"\n\07You cannot send JOBLOG log files to ",recipient);
X      my_puts(out_buf);
X      return(FAILURE);
X   `7D
X   else
X   `7B
X      username = getenv("USER");
X
X      if(strcmp(recipient,username) == 0)
X      `7B
X`09 my_puts("\n\07You cannot send JOBLOG log files to yourself!");
X`09 return(FAILURE);
X      `7D
X   `7D
X
X   /* good recipient; get the account of the sender */
X
X   item_code = JPI$_ACCOUNT;
X   status = LIB$GETJPI(&item_code,0L,NULL,0L,&account_d,0);
X
X   if(!(status & SS$_NORMAL))
X      return(FAILURE);
X
X   /* strip off the trailing blanks in the account */
X
X   length = 0;
X
X   while(length < ACCOUNT_MAX && account`5Blength`5D != ' ')
X      ++length;
X
X   account`5Blength`5D = '\0';`09`09/* make it a string`09`09      */
X   squeeze_str(account);`09`09/* squeeze out any internal blanks    */
X
X   /* make a mail message for the recipient */
X
X   strcpy(tempfile,"JOBXXXXXX");
X   mktemp(tempfile);
X   strcat(tempfile,".TMP");
X
X   out_rab = cc$rms_rab;
X   out_rab.rab$l_fab = &out_fab;`09/* pointer to input FAB`09`09      */
X   out_rab.rab$b_rac = RAB$C_SEQ;`09/* sequential access for copy`09      */
X   out_rab.rab$w_usz = sizeof(out_buf);`09/* length of output buffer`09
V      */
X   out_rab.rab$l_rbf = out_buf;`09`09/* pointer to buffer`09`09      */
X
X   out_fab = cc$rms_fab;
X   out_fab.fab$w_ifi = 0; `09`09/* reset this!`09`09`09      */
X   out_fab.fab$b_fac = FAB$M_PUT;
X
X   out_fab.fab$l_fna = tempfile;
X   out_fab.fab$b_fns = (UCHAR) strlen(tempfile);
X
X   /* open the output file */
X
X   status = SYS$CREATE(&out_fab);
X
X   if(status != RMS$_NORMAL)
X   `7B
X      SYS$CLOSE(&out_fab);
X      return(FAILURE);
X   `7D
X
X   /* connect the output file's RMS blocks */
X
X   status = SYS$CONNECT(&out_rab);
X
X   if(status != RMS$_NORMAL)
X   `7B
X      SYS$CLOSE(&out_fab);
X      return(FAILURE);
X   `7D
X
X   if(verify)
X      verify_ptr = "";
X   else
X      verify_ptr = "n UNVERIFIED";
X
X   cat(out_buf,"There is a",verify_ptr,
X       " JOBLOG log file from ",username," waiting to be retrieved.");
X   out_rab.rab$w_rsz = (USHORT) strlen(out_buf);
X   status = SYS$PUT(&out_rab);
X
X   strcpy(out_buf,"To retrieve it, enter the command\n");
X   out_rab.rab$w_rsz = (USHORT) strlen(out_buf);
X   status = SYS$PUT(&out_rab);
X
X   cat(out_buf,"`09JOBLOG/RETRIEVE/USER=",username);
X   out_rab.rab$w_rsz = (USHORT) strlen(out_buf);
X   status = SYS$PUT(&out_rab);
X
X   status = SYS$CLOSE(&out_fab);
X
X   my_puts(" ");
X   cat(out_buf,"....sending mail to ",recipient,"....");
X   my_puts(out_buf);
X
X   /* create the command to be SPAWNed */
X
X   if(verify)
X      cat(command,"$MAIL/SUBJECT=\"JOBLOG pending from ",username,"\" ",
X`09  tempfile," ",recipient);
X   else
X      cat(command,
X`09  "$MAIL/SUBJECT=\"UNVERIFIED JOBLOG pending from ",username,"\" ",
X`09  tempfile," ",recipient);
X
X   command_d.dsc$w_length = (USHORT) strlen(command);
X
X   /* SYSPRV is needed to spawn */
X
X   privs.prv$v_sysprv = ON;
X
X   status = SYS$SETPRV(ON,&privs,FALSE,NULL);
X
X   if(!(status & SS$_NORMAL))
X   `7B
X      LIB$SIGNAL(status);
X      return;
X   `7D
X
X   /* now try to spawn the command to mail the notice */
X
X   status = LIB$SPAWN(&command_d,&null_d,&null_d,NULL,NULL,0L,&status2,0L,0L
V,
X`09`09      0L,0L,NULL,NULL);
X
X   /* kill SYSPRV now just to be safe */
X
X   status2 = SYS$SETPRV(OFF,&privs,FALSE,NULL);
X
X   if(!(status2 & SS$_NORMAL))
X      LIB$SIGNAL(status2);
X
X   privs.prv$v_sysprv = OFF;
X
X   delete_log(tempfile);`09`09/* kill it before we forget`09      */
X
X   /* now check to see if spawn worked */
X
X   if(!(status & SS$_NORMAL))
X   `7B
X      LIB$SIGNAL(JLG_NO_SPAWN);
X      return(FAILURE);
X   `7D
X
X   /* create the filename that will be used when the log file is moved
X    * to the staging area
X    */
X
X   time_val = time(NULL);`20
X   time_ptr = localtime(&time_val);
X   time_ptr->tm_mon += 1;`09`09/* because it is 0-11, not 1-12`09:-(   */
X
X   /* create the filename that will be used when the log file is copied
X    * to the staging area
X    */
X
X   if(verify)
X      verify_ch = "V";
X   else
X      verify_ch = "U";
X
X   status = SYS$FAO(&ctrstr_d,&length,&filename_d,(ULONG) strlen(stage_dir),
X`09`09    stage_dir,(ULONG) strlen(username),username,
X`09`09    (ULONG) strlen(recipient),recipient,
X`09`09    (ULONG) strlen(account),account,
X`09`09    strlen(verify_ch),verify_ch,time_ptr->tm_mon/10,
X`09`09    time_ptr->tm_mon%10,time_ptr->tm_mday/10,
X`09`09    time_ptr->tm_mday%10,time_ptr->tm_year/10,
X`09`09    time_ptr->tm_year%10,time_ptr->tm_hour/10,
X`09`09    time_ptr->tm_hour%10,time_ptr->tm_min/10,
X`09`09    time_ptr->tm_min%10,time_ptr->tm_sec/10,
X`09`09    time_ptr->tm_sec%10);
X
X   /* copy the log file to the staging directory */
X
X   status = copy_file(logfile,filename,TRUE);
X
X   if(status == SUCCESS)
X   `7B
X      if(verify)
X`09 cat(out_buf,"\n\nNotification of VERIFIED JOBLOG sent to user ",
X`09     recipient,"\n\n");
X      else
X`09 cat(out_buf,"\n\nNotification of UNVERIFIED JOBLOG sent to user ",
X`09     recipient,"\n\n");
X
X      my_puts(out_buf);
X   `7D
X
X   return(status);
X
X`7D`09/*** mail_log ***/
X`0C
X/***************************************************************************
V****
X****************************************************************************
V****
X
X  Function:`09valid_recip
X
X  Purpose:`09Determine if the user specified is allowed to received mailed
X`09`09JOBLOG log files.
X
X  Formal Parameters:
X
X`09Name`09`09`09Description
X`09----`09`09`09-----------
X`09recipient`09`09who is supposed to get the log file
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`09SUCCESS`09`09`09valid recipient
X`09FAILURE`09`09`09invalid recipient
X
X****************************************************************************
V****
X****************************************************************************
V***/
X
Xstatic USHORT valid_recip(char *recipient)
X
X`7B`09/*** valid_recip ***/
X`09`09`09`09`09/********   LOCAL  VARIABLES   ********/
X`09 ULONG`09  id,`09`09`09/* current id held by recipient`09      */
X`09`09  context,`09`09/* for getting individual identifiers */
X`09`09  status;`09`09/* return code status holder`09      */
X`09 USHORT`09  i,`09`09`09/* loop and array index`09`09      */
X`09`09  j;`09`09`09/* ditto......`09`09`09      */
Xstatic`09 ULONG`09  uic`5B2`5D;`09`09/* so we can get identifiers`09      */
Xstatic`09 USHORT`09  length;`09`09/* from SYS$GETUAI`09`09      */
Xstatic`09 ID_DEF   valid_ids`5B`5D = `7B
X`7B"FACULTY",0L`7D,
X`7B"STAFF",0L`7D,
X`7B"JOBLOG_RECIPIENT",0L`7D,
X`7B0L,0L`7D`7D;
Xstatic`09 ITM_LST  items`5B`5D = `7B
X`7Bsizeof(uic),UAI$_UIC,&uic`5B0`5D,&length`7D,
X`7B0,0,NULL,NULL`7D`7D;
Xstatic $DESCRIPTOR(recip_d,"");
Xstatic $DESCRIPTOR(id_d,"");
X
X
X   /* translate all of the ASCII identifiers to integer to make them easier
X    * to compare later
X    */
X
X   i = 0;
X
X   while(valid_ids`5Bi`5D.id_string != NULL)
X   `7B
X      id_d.dsc$a_pointer = valid_ids`5Bi`5D.id_string;
X      id_d.dsc$w_length = (USHORT) strlen(id_d.dsc$a_pointer);
X
X      status = SYS$ASCTOID(&id_d,&(valid_ids`5Bi`5D.id),NULL);
X      i++;
X   `7D
X
X   privs.prv$v_sysprv = ON;`09`09/* need SYSPRV to get UAF record      */
X
X   status = SYS$SETPRV(ON,&privs,FALSE,NULL);
X
X   if(!(status & SS$_NORMAL))
X   `7B
X      LIB$SIGNAL(status);
X      return;
X   `7D
X
X   /* get the recipient's UIC from UAF */
X
X   recip_d.dsc$a_pointer = recipient;
X   recip_d.dsc$w_length = (USHORT) strlen(recipient);
X
X   status = SYS$GETUAI(0L,0L,&recip_d,&items,0L,0L,0L);
X
X   if(!(status & SS$_NORMAL))
X      return(FAILURE);
X
X   status = SYS$SETPRV(OFF,&privs,FALSE,NULL);
X
X   if(!(status & SS$_NORMAL))
X   `7B
X      LIB$SIGNAL(status);
X      return;
X   `7D
X
X   privs.prv$v_sysprv = OFF;
X
X   /* now get each identifer the recipient holds and see if it is valid */
X
X   context = 0L;
X   status = SYS$FIND_HELD(&uic,&id,NULL,&context);
X
X   while(status == SS$_NORMAL)
X   `7B
X      /* got an identifier; now check if it is a good one */
X
X      for(j = 0; j < i; j++)
X      `7B
X`09 if(id == valid_ids`5Bj`5D.id)
X`09 `7B
X`09    status = SYS$FINISH_RDB(&context);
X`09    return(SUCCESS);
X`09 `7D
X      `7D
X
X      status = SYS$FIND_HELD(&uic,&id,NULL,&context);
X   `7D
X
X   if(status != SS$_NOSUCHID)
X      status = SYS$FINISH_RDB(&context);
X
X   /* bad recipient if we get here */
X
X   return(FAILURE);
X
X`7D`09/*** valid_recip ***/
X`0C
X/***************************************************************************
V****
X****************************************************************************
V****
X
X  Function:`09save_log
X
X  Purpose:`09Save a log file for a user.  Use the filename specified by
X`09`09the user if one exists, otherwise use a default name.
X
X  Formal Parameters:
X
X`09Name`09`09`09Description
X`09----`09`09`09-----------
X`09log_file`09`09name of log file
X  `09channel`09`09`09TTY channel
X
X  Global variables:
X
X`09Name`09`09`09Examine/Modify/Use/Read/Write
X`09----`09`09`09-----------------------------
X`09disp_failed`09`09   X
X
X  Return Codes:
X
X`09Code`09 `09`09Reason
X`09----`09`09`09------
X`09SUCCESS
X`09FAILURE
X`09CANCEL
X`09status`09`09`09return code from save_log()
X
X****************************************************************************
V****
X****************************************************************************
V***/
X
Xstatic ULONG save_log(char *logfile,USHORT channel)
X
X`7B`09/*** save_log ***/
X`09`09`09`09`09/********   LOCAL  VARIABLES   ********/
X`09 ULONG`09  status;`09`09/* return code status holder`09      */
X`09 USHORT`09  length;`09`09/* length of command line value`09      */
X`09 IOSB_DEF iosb;`09`09`09/* for reading from the TTY`09      */
X`09 char`09  savefile`5BNAM$C_MAXRSS+1`5D, /* filename to use for /SAVEing
V   */
X`09`09  deffile`5BNAM$C_MAXRSS+1`5D, /* default filename`09`09      */
X`09`09  buffer`5BNAM$C_MAXRSS*2`5D, /* for formatting message`09      */
X`09`09  prompt`5BTEMPBUF_MAX+1`5D; /* for asking for filename`09      */
X$DESCRIPTOR(save_d,"SAVE");`09`09/* for parsing /SAVE`09`09      */
X$DESCRIPTOR(savefile_d,savefile);`09/* for getting /SAVE value`09      */
X
X
X   status = CLI$GET_VALUE(&save_d,&savefile_d,&length);
X
X   if(status == SS$_NORMAL && !disp_failed)
X   `7B
X      savefile`5Blength`5D = '\0';`09`09/* make it a string`09`09      */
X   `7D
X   else
X   `7B
X      /* filename wasn't specified; prompt the user for it */
X
X      strcpy(deffile,"JOBXXXXXX");`09/* make a filename for them`09      */
X      mktemp(deffile);
X      strcat(deffile,".LOG");
X      my_puts(" ");
X      my_puts("What filename should be used for the log file?");
X      cat(prompt,"`5Bdefault is ",deffile,"`5D ");
X      status = my_gets(channel,savefile,prompt,&length,sizeof(savefile) - 1)
V;
X
X      if(status == FAILURE)
X`09 return(FAILURE);
X      else if(status == CANCEL)
X`09 return(CANCEL);
X
X      str_pref_trim(savefile);
X      str_post_trim(savefile);
X
X      if(savefile`5B0`5D == '\0')
X`09 strcpy(savefile,deffile);
X      else
X`09 strlu(savefile);`09`09/* convert to all uppercase`09      */
X   `7D
X
X   /* now copy the file */
X
X   status = copy_file(logfile,savefile,FALSE);
X
X   if(status == SUCCESS)
X   `7B
X      cat(buffer,"\n\nLog file closed to ",savefile);
X      my_puts(buffer);
X   `7D
X
X   return(status);
X
+-+-+-+-+-+-+-+-  END  OF PART 4 +-+-+-+-+-+-+-+-
