-+-+-+-+-+-+-+-+ START OF PART 4 -+-+-+-+-+-+-+-+ X`09Code`09 `09`09Reason X`09----`09`09`09------ X`09SUCCESS X`09FAILURE 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 return(SUCCESS); 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 /* 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 /* 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 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 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 char`09 outfile`5B`5D = "jobXXXXXX"; X`09 IOSB_DEF iosb;`09`09`09/* for reading from the TTY`09 */ Xstatic`09 char`09 buffer`5BNAM$C_MAXRSS+1`5D, /* filename to use for /SAVEi Vng */ X`09`09 buffer2`5BNAM$C_MAXRSS*2`5D, /* for formatting message`09 */ X`09`09 prompt`5B`5D = X`09`09 `7B"What filename should be used for the log file? "`7D; Xstatic $DESCRIPTOR(save_d,"SAVE");`09/* for parsing /SAVE`09`09 */ Xstatic $DESCRIPTOR(buf_d,buffer);`09/* for getting /SAVE value`09 */ X X X status = CLI$GET_VALUE(&save_d,&buf_d,&length); X X if(status == SS$_NORMAL && !disp_failed) X `7B X buffer`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 my_puts(" "); X status = SYS$QIOW(0,channel,IO$_READVBLK`7CIO$_READPROMPT,&iosb,0,0,bu Vffer, X`09`09`09(ULONG) NAM$C_MAXRSS,0,0,prompt,sizeof(prompt)); X X if(status != SS$_NORMAL) X`09 return(FAILURE); X X if(iosb.count == 0 && iosb.terminator == CONTROL_Z) X`09 return(SUCCESS);`09`09/* user changed his/her mind`09 */ X X buffer`5Biosb.count`5D = '\0';`09/* make it a string`09`09 */ X squeeze_str(buffer);`09`09/* squeeze out all of the spaces */ X X if(buffer`5B0`5D == '\0') X `7B X`09 strcpy(buffer,"JOBXXXXXX");`09/* make a filename for them`09 */ X`09 mktemp(buffer); X`09 strcat(buffer,".LOG"); X `7D X else X`09 strlu(buffer);`09`09`09/* convert to all uppercase`09 */ X `7D X X /* now copy the file */ X X status = copy_file(logfile,buffer); X X if(status == SUCCESS) X `7B X cat(buffer2,"\n\nLog file closed to ",buffer); X my_puts(buffer2); X `7D X else X my_puts("\n\n\7*ERROR* Unable to copy logfile to your area\n"); X X return(status); X X`7D`09/*** save_log ***/ X`0C X/*************************************************************************** V**** X**************************************************************************** V**** X X Function:`09retrieve_log X X Purpose:`09Allow a user to retrieve JOBLOG file(s). X X Formal Parameters: X X`09Name`09`09`09Description X`09----`09`09`09----------- X`09stage_dir`09`09staging directory for log files 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`09return code from user_retrieve or X`09`09`09`09class_retrieve X X**************************************************************************** V**** X**************************************************************************** V***/ X Xstatic ULONG retrieve_log(char *stage_dir,ARG_DEF *args) X X`7B`09/*** retrieve_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 buf`09`09 */ X`09`09 channel;`09`09/* TTY channel`09`09`09 */ X`09 char`09 buf`5BBUFSIZ`5D;`09`09/* for storing the retrieve key`09 * V/ X$DESCRIPTOR(buf_d,buf);`09`09`09/* for getting retrieve key string */ X$DESCRIPTOR(class_d,"CLASS");`09`09/* to check for /CLASS`09`09 */ X$DESCRIPTOR(user_d,"USER");`09`09/* to check for /USER`09`09 */ X X if(CLI$PRESENT(&class_d) == CLI$_PRESENT) X `7B X /* get the class string */ X X status = CLI$GET_VALUE(&class_d,&buf_d,&length); X X if(status == SS$_NORMAL) X `7B X`09 buf`5Blength`5D = '\0';`09`09/* make it a string`09`09 */ X`09 status = class_retrieve(stage_dir,buf); X `7D X else X`09 status = FAILURE; X `7D X else if(CLI$PRESENT(&user_d) == CLI$_PRESENT) X `7B X /* get the user string */ X X status = CLI$GET_VALUE(&user_d,&buf_d,&length); X X if(status == SS$_NORMAL) X `7B X`09 buf`5Blength`5D = '\0';`09`09/* make it a string`09`09 */ X`09 status = user_retrieve(stage_dir,buf); X `7D X else X`09 status = FAILURE; X `7D X X return(status); X X`7D`09/*** retrieve_log ***/ X`0C X/*************************************************************************** V**** X**************************************************************************** V**** X X Function:`09user_retrieve X X Purpose:`09Allow a user to retrieve a JOBLOG file that s/he "owns". X X Formal Parameters: X X`09Name`09`09`09Description X`09----`09`09`09----------- X`09stage_dir`09`09staging directory for log files X`09from`09`09`09user who sent the log file 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`09SUCCESS X`09FAILURE X X**************************************************************************** V**** X**************************************************************************** V***/ X Xstatic ULONG user_retrieve(char *stage_dir,char *from) X X`7B`09/*** user_retrieve ***/ X`09`09`09`09`09/******** LOCAL VARIABLES ********/ X`09 ULONG`09 fcontext,`09`09/* file context for getting file */ X`09`09 status;`09`09/* return code status holder`09 */ X`09 char`09 *tptr;`09`09/* temporary character pointer`09 */ X`09 USHORT`09 verified;`09`09/* set if log is VERIFIED`09 */ X`09 char`09 newfile`5BNAM$C_MAXRSS+1`5D, /* what to copy logfile to`09 V */ X`09`09 username`5BUSERNAME_MAX+1`5D, /* who sent the log file`09 */ X`09`09 recipient`5BUSERNAME_MAX+1`5D, /* who the log file was sent to */ X`09`09 filename`5BNAM$C_MAXRSS+1`5D, /* for wildcard searching`09 */ X`09`09 logfile`5BNAM$C_MAXRSS+1`5D, /* logfile name`09`09 */ X`09`09 tempbuf`5BTEMPBUF_MAX+1`5D; X$DESCRIPTOR(file_d,filename); X$DESCRIPTOR(file2_d,logfile); X X X /* make the wildcard filename to be used */ X X cat(filename,stage_dir,from,"_",getenv("USER"),"_*.*"); X `20 X file_d.dsc$w_length = (USHORT) strlen(filename); X fcontext = 0L; X X /* see if the file exists */ X X status = LIB$FIND_FILE(&file_d,&file2_d,&fcontext); X X if(status != RMS$_NORMAL) X `7B X cat(tempbuf,"\n\7No log file for you from user ",from,"\n\n",from); X my_puts(tempbuf); X return(FAILURE); X `7D X X tptr = strchr(logfile,' ');`09`09/* find the end of the filename`09 V */ X *tptr = '\0';`09`09`09/* make the filename a string`09 */ X X /* find out if the log file was verified */ X X parse_filename(logfile,NULL,NULL,&verified); X X if(verified) X cat(newfile,from,".JOBLOG"); X else X cat(newfile,from,".UNVERIFIED_JOBLOG"); X X status = copy_file(logfile,newfile);`09/* copy the log file to user's are Va */ X X if(status == SUCCESS) X `7B X delete(logfile); X cat(tempbuf,"\n\nJOBLOG from user ",from," successfully retrieved.\n") V; X my_puts(tempbuf); X cat(tempbuf,"The file is ",newfile,".\n\n"); X my_puts(tempbuf); X `7D X else X `7B X cat(tempbuf,"\n\7*ERROR* retrieving JOBLOG from user ",from,".\n"); X my_puts(tempbuf); X `7D X X return(status); X X`7D`09/*** user_retrieve ***/ X`0C X/*************************************************************************** V**** X**************************************************************************** V**** X X Function:`09class_retrieve X X Purpose:`09Allow a user to retrieve JOBLOG file(s) for an entire class. X X Formal Parameters: X X`09Name`09`09`09Description X`09----`09`09`09----------- X`09stage_dir`09`09staging directory for log files X`09class`09`09`09class to be retrieved 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`09SUCCESS X`09FAILURE X X**************************************************************************** V**** X**************************************************************************** V***/ X Xstatic ULONG class_retrieve(char *stage_dir,char *class) X X`7B`09/*** class_retrieve ***/ X`09`09`09`09`09/******** LOCAL VARIABLES ********/ X`09 ULONG`09 fcontext,`09`09/* file context for getting file */ X`09`09 status;`09`09/* return code status holder`09 */ X`09 char`09 *name_ptr,`09`09/* pointer to filename of logfile */ X`09`09 *tptr;`09`09/* temporary character pointer`09 */ X`09 USHORT`09 count = 0,`09`09/* number of files retrieved`09 */ X`09`09 length,`09`09/* length of formatted string`09 */ X`09`09 verified;`09`09/* set if log file is VERIFIED`09 */ X`09 char`09 newfile`5BNAM$C_MAXRSS+1`5D, /* what to copy logfile to`09 V */ X`09`09 username`5BUSERNAME_MAX+1`5D, /* who sent the log file`09 */ X`09`09 filename`5BNAM$C_MAXRSS+1`5D, /* for wildcard searching`09 */ X`09`09 logfile`5BNAM$C_MAXRSS+1`5D, /* logfile name`09`09 */ X`09`09 tempbuf`5BTEMPBUF_MAX+1`5D; X$DESCRIPTOR(file_d,filename); X$DESCRIPTOR(file2_d,logfile); X$DESCRIPTOR(format_d,"\n\n!ZW files retrieved for class !AD.\n\n"); X$DESCRIPTOR(buffer_d,tempbuf); X X /* create the wildcard name for retrieving files */ X X squeeze_str(class);`09`09`09/* make sure class is free of spaces */ X cat(filename,stage_dir,"*_",getenv("USER"),"_",class,".*JOBLOG*;*"); X file_d.dsc$w_length = (USHORT) strlen(filename); X fcontext = 0L; X X status = LIB$FIND_FILE(&file_d,&file2_d,&fcontext); X X while(status == RMS$_NORMAL) X `7B X count++;`09`09`09`09/* count it`09`09`09 */ X tptr = strchr(logfile,' '); X *tptr = '\0';`09`09`09/* make filename a real string`09 */ X X name_ptr = strchr(logfile,'`5D') + 1L; /* skip past directory spec`09 V */ X X /* create the filename that the log file is to be copied to */ X X parse_filename(name_ptr,username,NULL,&verified); X X if(verified) X`09 cat(newfile,username,".JOBLOG"); X else X`09 cat(newfile,username,".UNVERIFIED_JOBLOG"); X X if(copy_file(logfile,newfile) == SUCCESS) X`09 delete(logfile); X else X `7B X`09 cat(tempbuf,"\n\n\7*ERROR* copying log file ",logfile, X`09 " to your area\n"); X `7D X X status = LIB$FIND_FILE(&file_d,&file2_d,&fcontext); X `7D X X if(status == RMS$_FNF) X `7B X cat(tempbuf,"\7\n\nNo JOBLOG files for you from class ",class,"\n\n"); X my_puts(tempbuf); X return; X `7D X X if(status != RMS$_NMF)`09`09/* did we stop for the right reason? */ X LIB$STOP(status);`09`09`09/* nope.....`09`09`09 */ X X /* terminate the "finding" of files */ X X status = LIB$FIND_FILE_END(&fcontext); X X if((status != SS$_NORMAL) && (status != RMS$_NORMAL)) X LIB$STOP(status); X X status = SYS$FAO(&format_d,&length,&buffer_d,count,(ULONG) strlen(class), X`09`09 class); X X if(status != SS$_NORMAL) X LIB$SIGNAL(status); X X tempbuf`5Blength`5D = '\0'; X my_puts(tempbuf); X X return; X X`7D`09/*** class_retrieve ***/ X`0C X/*************************************************************************** V**** X**************************************************************************** V**** X X Function:`09delete_mlog X X Purpose:`09Allow a user to delete JOBLOG file(s) from the staging area. X X Formal Parameters: X X`09Name`09`09`09Description X`09----`09`09`09----------- X`09stage_dir`09`09staging directory for log files 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`09SUCCESS X`09FAILURE X X**************************************************************************** V**** X**************************************************************************** V***/ X Xstatic ULONG delete_mlog(char *stage_dir) X X`7B`09/*** delete_mlog ***/ X`09`09`09`09`09/******** LOCAL VARIABLES ********/ X`09 ULONG`09 status,`09`09/* return code status holder #1`09 */ X`09`09 status2,`09`09/* " " " " #2`09 */ X`09`09 fcontext;`09`09/* context for FINDing files`09 */ X`09 USHORT`09 length;`09`09/* length of buffer`09`09 */ X`09 char`09 *username,`09`09/* name of user doing the deleting */ X`09`09 *tptr,`09`09/* temporary character pointer`09 */ X`09`09 filename`5BNAM$C_MAXRSS+1`5D, /* logfile name`09`09 */ X`09`09 logfile`5BNAM$C_MAXRSS+1`5D, /* output of LIB$FIND_FILE`09 */ X`09`09 command`5BCOMMAND_MAX+1`5D, /* MAIL command buffer`09 */ X`09`09 buffer`5BBUFSIZ+1`5D;`09/* buffer for reading from TTY`09 */ X$DESCRIPTOR(command_d,command); X$DESCRIPTOR(delete_d,"DELETE"); X$DESCRIPTOR(buf_d,buffer); X$DESCRIPTOR(null_d,""); X$DESCRIPTOR(file_d,""); X$DESCRIPTOR(file2_d,""); X$DESCRIPTOR(prompt_d,""); Xstatic`09 union`09 prvdef _align(longword) privs; X X X /* get the name of the user to whom the log file was mailed */ X X status = CLI$GET_VALUE(&delete_d,&buf_d,&length); X X if(status == SS$_NORMAL) X buffer`5Blength`5D = '\0';`09`09/* make it a string`09`09 */ X else X `7B X status = my_gets(buffer, X`09`09 "\n\nWho was the log file originally mailed to: ", X`09`09 &length,(USHORT) sizeof(buffer)); X X *(buffer + strlen(buffer) - 1) = '\0'; /* get rid of newline `09 V */ X strlu(buffer);`09`09`09/* conver to all uppercase`09 */ X `7D X X username = getenv("USER"); X X /* create the wildcard filespec that we'll use to check for log files */ X X cat(filename,stage_dir,username,"_",buffer,"_*.*JOBLOG_*"); X X file_d.dsc$a_pointer = filename; X file_d.dsc$w_length = (USHORT) strlen(filename); X file2_d.dsc$a_pointer = logfile; X file2_d.dsc$w_length = (USHORT) NAM$C_MAXRSS+1; X fcontext = 0L; X status2 = SUCCESS; X X status = LIB$FIND_FILE(&file_d,&file2_d,&fcontext); X X while(status == RMS$_NORMAL && status2 == SUCCESS) X `7B X tptr = strchr(logfile,' '); X *tptr = '\0';`09`09`09/* make filename a real string`09 */ X X if(delete(logfile) != 0)`09`09/* try to delete the file`09 */ X`09 LIB$SIGNAL(JLG_CANT_DELETE_LOG,1L,logfile); X else X `7B X`09 cat(command,"$MAIL/SUBJECT=\"JOBLOG from ",username, X`09 " has been deleted\"\ NL: ",buffer); X X`09 command_d.dsc$w_length = (USHORT) strlen(command); X X`09 /* now try to spawn the command to mail the notice */ X X`09 status = LIB$SPAWN(&command_d,&null_d,&null_d,NULL,NULL,0L,&status2, X`09`09`09 0L,0L,0L,0L,NULL,NULL); X X`09 if(status != SS$_NORMAL) X`09 LIB$SIGNAL(JLG_NO_SPAWN); X X`09 cat(command,"\nLogfile for user ",buffer," deleted.\n"); X`09 my_puts(command); X `7D X X status = LIB$FIND_FILE(&file_d,&file2_d,&fcontext); X `7D X X if(status == RMS$_FNF) X `7B X cat(command,"\7\n\nYou don't have any JOBLOG files for ",buffer, X`09 " pending.\n\n"); X my_puts(command); X return(FAILURE); X `7D X else`09if(status != RMS$_NMF)`09`09/* did we stop for the right reason? V */ X LIB$SIGNAL(status);`09`09/* nope.....`09`09`09 */ X X /* don't care if these fail because we'll be exiting shortly */ X X status = LIB$FIND_FILE_END(&fcontext); X status = SYS$SETPRV(OFF,&privs,FALSE,NULL); X X return(SUCCESS); X X`7D `09/*** delete_mlog ***/ X`0C X/*************************************************************************** V**** X**************************************************************************** V**** X X Function:`09get_logicals X X Purpose:`09Translate the logicals for JOBLOG$STAGE and JOBLOG$LOG X`09`09and save them for later. X X Formal Parameters: X X`09Name`09`09`09Description X`09----`09`09`09----------- X`09log_dir`09`09`09where to store translation of JOBLOG$LOG X`09stage_dir`09`09where to store translation of JOBLOG$STAGE 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**************************************************************************** V**** X**************************************************************************** V***/ X Xstatic void get_logicals(char *log_dir,char *stage_dir) X X`7B`09/*** get_logicals ***/ 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 resulting string`09 */ X`09 ITM_LST items`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$DESCRIPTOR(table_d,"LNM$SYSTEM"); X$DESCRIPTOR(logdir_d,"JOBLOG$LOG"); X$DESCRIPTOR(stagedir_d,"JOBLOG$STAGE"); X X X items`5B0`5D.buf_len = NAM$C_MAXRSS; X items`5B0`5D.buf_addr = log_dir; X items`5B0`5D.ret_len = &length;`09`09/* store it right back in length V */ X X status = SYS$TRNLNM(0,&table_d,&logdir_d,0,items); X X if(status != SS$_NORMAL) X LIB$STOP(JLG_NO_LOGICAL,1L,logdir_d.dsc$a_pointer); X X *(log_dir + length) = '\0';`09`09/* terminate it`09`09`09 */ X X items`5B0`5D.buf_addr = stage_dir; X X status = SYS$TRNLNM(0,&table_d,&stagedir_d,0,items); X X if(status != SS$_NORMAL) X LIB$STOP(JLG_NO_LOGICAL,1L,stagedir_d.dsc$a_pointer); X X *(stage_dir + length) = '\0';`09/* terminate it`09`09`09 */ X return; X X`7D`09/*** get_logicals ***/ X`0C X/*************************************************************************** V**** X**************************************************************************** V**** X X Function:`09get_char X X Purpose:`09Get a single character from the terminal in a safe way. gets X`09`09is notoriously dangerous (just ask anyone who was hit by the X`09`09Internet worm :-). X X Formal Parameters: X X`09Name`09`09`09Description X`09----`09`09`09----------- X`09prompt`09`09`09prompt to use 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**************************************************************************** V**** X**************************************************************************** V***/ X Xstatic void get_char(char *ch,char *prompt) X X`7B`09/*** get_char ***/ 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 input from terminal */ Xstatic`09 char`09 buffer`5B2`5D;`09`09/* to store one character`09 */ Xstatic $DESCRIPTOR(buffer_d,buffer);`09/* where the character is stored V */ Xstatic $DESCRIPTOR(prompt_d,"");`09/* prompt descriptor`09`09 */ X X X prompt_d.dsc$a_pointer = prompt; X prompt_d.dsc$w_length = (USHORT) strlen(prompt); X X length = 0; X status = LIB$GET_INPUT(&buffer_d,&prompt_d,&length); X X if(status != SS$_NORMAL && status != LIB$_INPSTRTRU) X *ch = '\0';`09`09`09/* problems...`09`09`09 */ X else if(length == 0) X *ch = CARRIAGE_RETURN;`09`09/* just a ....`09`09 */ X else X *ch = buffer`5B0`5D; X X return; X X`7D`09/*** get_char ***/ X`0C X/*************************************************************************** V**** X**************************************************************************** V**** X X Function:`09ctrly_trap X X Purpose:`09Set up the AST for trapping control-Y. X X Formal Parameters: X X`09Name`09`09`09Description X`09----`09`09`09----------- X`09channel`09`09`09channel assigned to SYS$INPUT 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`09SUCCESS`09`09`09successful completion X`09FAILURE`09`09`09unable to set control-Y AST X X**************************************************************************** V**** X**************************************************************************** V***/ X Xstatic ULONG ctrly_trap(USHORT *channel) X X`7B`09/*** ctrly_trap ***/ X X if(SYS$QIOW(0,*channel,IO$_SETMODE `7C IO$M_CTRLYAST,0,0,0,ctrly_ast,chan Vnel, X`09 0,0,0,0) != SS$_NORMAL) X return(FAILURE); X X return(SUCCESS); X X`7D`09/*** ctrly_trap ***/ X`0C X/*************************************************************************** V**** X**************************************************************************** V**** X X Function:`09ctrly_ast X X Purpose:`09AST routine alled when control-Y is detected. X X Formal Parameters: X X`09Name`09`09`09Description X`09----`09`09`09----------- 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`09none 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 ctrly_ast(USHORT *channel) X X`7B`09/*** ctrly_ast ***/ X X ctrly_trap(channel);`09`09`09/* reset the control-Y AST`09 */ X return; X X`7D`09/*** ctrly_ast ***/ X`0C X/*************************************************************************** V**** X**************************************************************************** V**** X X Function:`09ctrlc_trap X X Purpose:`09Set up the AST for trapping control-C. X X Formal Parameters: X X`09Name`09`09`09Description X`09----`09`09`09----------- X`09channel`09`09`09channel assigned to SYS$INPUT 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`09SUCCESS`09`09`09successful completion X`09FAILURE`09`09`09unable to set control-C AST X X**************************************************************************** V**** X**************************************************************************** V***/ X Xstatic ULONG ctrlc_trap(USHORT *channel) X X`7B`09/*** ctrlc_trap ***/ X X if(SYS$QIOW(0,*channel,IO$_SETMODE `7C IO$M_CTRLCAST,0,0,0,ctrlc_ast,chan Vnel, X`09 0,0,0,0) != SS$_NORMAL) X return(FAILURE); X X return(SUCCESS); X X`7D`09/*** ctrlc_trap ***/ X`0C X/*************************************************************************** V**** X**************************************************************************** V**** X X Function:`09ctrlc_ast X X Purpose:`09AST routine alled when control-C is detected. X X Formal Parameters: X X`09Name`09`09`09Description X`09----`09`09`09----------- 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`09none 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 ctrlc_ast(USHORT *channel) X X`7B`09/*** ctrlc_ast ***/ X X ctrlc_trap(channel);`09`09`09/* reset the control-C AST`09 */ X return; X X`7D`09/*** ctrlc_ast ***/ X`0C X/*************************************************************************** V**** X**************************************************************************** V**** X X Function:`09joblog_check X X Purpose:`09Make sure that the user isn't already running JOBLOG. 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`09none 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 joblog_check(void) X X`7B`09/*** joblog_check ***/ X`09`09`09`09`09/******** LOCAL VARIABLES ********/ X`09 ULONG`09 status,`09`09/* return code status holder`09 */ X`09`09 owner;`09`09/* parent process PID`09`09 */ X`09 short`09 length;`09`09/* length of process name`09 */ X`09 char`09 procname`5BPNAME_MAX+1`5D,/* current process name array`09 V */ X`09`09 newpname`5BPNAME_MAX+1`5D;/* process name for JOBLOG subprocess */ X$DESCRIPTOR(procname_d,procname);`09/* for getting process name`09 */ X$DESCRIPTOR(newpname_d,newpname);`09/* for creating new process name */ X$DESCRIPTOR(format_d,"JOBLOG_!XL");`09/* for formatting test process name V */ X X X /* make sure that the user doesn't run JOBLOG while they are already in X * JOBLOG X */ X X status = LIB$GETJPI(&JPI$_PRCNAM,0,0,0,&procname_d,&length); X X if(status != SS$_NORMAL) X LIB$STOP(status); X X procname`5Blength`5D = '\0'; X X status = LIB$GETJPI(&JPI$_OWNER,0,0,&owner,0,0); X X if(status != SS$_NORMAL) X LIB$STOP(status); X X /* create what would the process name be if the user ran JOBLOG while X * in JOBLOG X */ X X status = SYS$FAO(&format_d,&length,&newpname_d,owner & 0xFFFF); X X if(status != SS$_NORMAL) X LIB$STOP(status); X X newpname`5Blength`5D = '\0'; X X if(!strcmp(newpname,procname)) X LIB$STOP(JLG_INUSE); X X return; X X`7D`09/*** joblog_check ***/ X`0C X/*************************************************************************** V**** X**************************************************************************** V**** X X Function:`09skim X X Purpose:`09Skim the JOBLOG staging directory for old JOBLOG files, de- X`09`09leting them if they are older than the /WAIT value and warning X`09`09senders if they are older then the /WARN value. 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`09stage_dir`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 skim(void) X X`7B`09/*** skim ***/ X`09`09`09`09`09/******** LOCAL VARIABLES ********/ X`09 char`09 *ptr;`09`09`09/* for skipping dev/directory spec */ X`09 ULONG`09 fcontext,`09`09/* file context for getting file */ X`09`09 status,`09`09/* return code status holder`09 */ X`09`09 wait_days,`09`09/* # days before deleting log`09 */ X`09`09 warn_days;`09`09/* # days before warning people`09 */ X`09 time_t`09 cur_time;`09`09/* current time value`09`09 */ X`09 USHORT`09 length;`09`09/* for trimming trailing blanks`09 */ Xstruct`09 stat`09 statbuf;`09`09/* for getting file's age`09 */ X`09 char`09 wildname`5BNAM$C_MAXRSS+1`5D, X`09`09 filename`5BNAM$C_MAXRSS+1`5D, X`09`09 buf`5BINT_STR_MAX+1`5D;`09/* for getting int strings`09 */ X$DESCRIPTOR(wild_d,wildname); X$DESCRIPTOR(file_d,filename); X$DESCRIPTOR(wait_d,"WAIT"); X$DESCRIPTOR(warn_d,"WARN"); X$DESCRIPTOR(buf_d,buf); X X X if(CLI$PRESENT(&wait_d) == CLI$_PRESENT) X `7B X /* get the class string */ X X status = CLI$GET_VALUE(&wait_d,&buf_d,&length); X X if(status == SS$_NORMAL) X`09 buf`5Blength`5D = '\0';`09`09/* make it a string`09`09 */ X else X`09 LIB$STOP(status); X X wait_days = (ULONG) atol(buf); X `7D X X if(CLI$PRESENT(&warn_d) == CLI$_PRESENT) X `7B X /* get the class string */ X X status = CLI$GET_VALUE(&warn_d,&buf_d,&length); X X if(status == SS$_NORMAL) X`09 buf`5Blength`5D = '\0';`09`09/* make it a string`09`09 */ X else X`09 LIB$STOP(status); X X warn_days = (ULONG) atol(buf); X `7D X X fcontext = 0L; X time(&cur_time); X strcpy(wildname,stage_dir); X strcat(wildname,"*.*;*");`09`09/* look at all files`09`09 */ X wild_d.dsc$w_length = (USHORT) strlen(wildname); X X status = LIB$FIND_FILE(&wild_d,&file_d,&fcontext); X X while(status == RMS$_NORMAL) X `7B X length = 0; X X while(length < NAM$C_MAXRSS && filename`5Blength`5D != ' ') X ++length; X X filename`5Blength`5D = '\0';`09`09/* make it a string`09`09 */ X stat(filename,&statbuf);`09`09/* to find out how old it is`09 */ X X /* should we delete or warn the sender and recipient? */ X X if(statbuf.st_atime < (cur_time - (wait_days * SECONDS_IN_DAY))) X`09 delete(filename); X else if(statbuf.st_atime < (cur_time - (warn_days * SECONDS_IN_DAY))) X `7B X`09 ptr = (char *) (strchr(filename,'`5D') + 1L); X`09 warn(ptr,wait_days - warn_days); X `7D X X status = LIB$FIND_FILE(&wild_d,&file_d,&fcontext); X `7D X X return; X X`7D`09/*** skim ***/ X`0C X/*************************************************************************** V**** X**************************************************************************** V**** X X Function:`09warn X X Purpose:`09Warn the sender and recipient of a logfile. X X Formal Parameters: X X`09Name`09`09`09Description X`09----`09`09`09----------- X`09filename`09`09log file name X`09days`09`09`09number of days before the log file will X`09`09`09`09be deleted 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**************************************************************************** V**** X**************************************************************************** V***/ X Xstatic void warn(char *filename,USHORT days) X X`7B`09/*** warn ***/ X`09`09`09`09`09/******** LOCAL VARIABLES ********/ X`09 ULONG`09 status,`09`09/* return code status holder`09 */ X`09`09 status2; X`09 USHORT`09 verified,`09`09/* set if log file is verified`09 */ X`09`09 length;`09`09/* length of formatted string`09 */ X`09 char`09 username`5BUSERNAME_MAX+1`5D, X`09`09 recipient`5BUSERNAME_MAX+1`5D, X`09`09 tempfile`5BNAM$C_MAXRSS+1`5D, X`09`09 out_buf`5BBUFSIZ`5D,`09/* formatting and I/O buffer`09 */ X`09`09 command`5BCOMMAND_MAX+1`5D; 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(command_d,""); X$DESCRIPTOR(out_buf_d,out_buf); X$DESCRIPTOR(format_d,"If it is not retrieved in !ZW days, it will be deleted V."); X$DESCRIPTOR(format2_d, X`09 "If it is not retrieved in !ZW days, it will be deleted."); X X X parse_filename(filename,username,recipient,&verified); 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; 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; X `7D X X /* warn the recipient */ X +-+-+-+-+-+-+-+- END OF PART 4 +-+-+-+-+-+-+-+-