From:	MERC::"uunet!WKUVX1.BITNET!FILESERV-Mgr" 12-JUN-1992 14:25:37.55
To:	galaxy::gleeve
CC:	
Subj:	JOBLOG.07_OF_07

-+-+-+-+-+-+-+-+ START OF PART 7 -+-+-+-+-+-+-+-+
X`09   ectory pointed to by the JOBLOG$LOG logical.  This directory is
X`09   protected RWED,,, so the user is never able to modify it.
X
X`092. During the session, the user has the option of toggling logging
X`09   on/off.  If logging is turned OFF, the log file immediately be-
X`09   comes UNVERIFIED, signifying that it is not a true record of the
X`09   login session.
X
X`093. After the user terminates the session, the user can:
X
X`09   a) print the log file
X
X`09      The log file is printed directly from the JOBLOG$LOG dir-
X`09      ectory with a job name that reflects whether it is VERIFIED
X`09      or UNVERIFIED.  The log file is deleted after printing.
X
X`09   b) delete the log file
X
X`09      The log file is deleted directly from the JOBLOG$LOG dir-
X`09      ectory.
X
X`09   c) save the log file
X
X`09      The log file is copied to the file specified by the user
X`09      and deleted from the JOBLOG$LOG directory.
X
X`09   d) mail notification of the log file to someone
X
X`09      The log file is move from the JOBLOG$LOG directory to the
X`09      staging directory pointed to by the JOBLOG$STAGE directory.
X`09      The log file will stay here until 1) it is picked up by the
X`09      recipient using the /RETRIEVE qualifier to JOBLOG, 2) de-
X`09      leted by the sender using the /DELETE qualifier, or 3) de-
X`09      leted automatically from a batch job using the /SKIM qualifer.
X
X`09      The batch job should run JOBLOG/SKIM/WAIT=n/WARN=m once per
X`09      day to keep the staging directory cleaned out.  The sender
X`09      and the recipient will be warned via e-mail that there is a
X`09      log file that hasn't been picked up after m days.  The log
X`09      file will be deleted from the staging area after n days and
X`09      both the sender and the recipient are notified.
X
X   All four of the choices in #3, as well as a number of other options, can
Xbe specified on the command line at startup.  If disposition of the log file
Xisn't specified on the command line, the user will be prompted for it.  See
Xthe help file for more information.
X
XA FEW WORDS ABOUT MAILING LOG FILES
X   The first question is why aren't log files simply mailed to the recipient
V?
XThe main reason is to give users an opportunity to delete log files if they
Xwant.  This would be impossible to do if the log files were actually in
Xthe recipient's mail file.
X
X   JOBLOG is setup so that only accounts that have a certain identifier can
Xreceive mailed logfiles.  The identifiers here that allow an account to
Xreceive mailed log files are FACULTY, STAFF, and JOBLOG_RECIPIENT (the last
Xwe grant on a need basis).  Also, users cannot mail log files to themselves
X(to prevent people from bypassing their disk quotas).  And since student
Xaccounts here don't have any of the above identifiers, they can't mail log
Xfiles to each other.  In a student environment, these might be reasonable
Xrestrictions.  If you want to change/delete/add identifiers, see the
Xvalid_ids array in the valid_recip() routine.
X
XINSTALLATION
X   1.  If you wish to build JOBLOG with PHOTO mode, do one of the following:
X
X`09a) If you have MMS installed on your system, edit the DESCRIP.MMS
X`09   file and change the CFLAGS definition to look like
X
X`09   CFLAGS=/optimize=noinline/define=PHOTO_MODE
X
X`09b) If you don't MMS installed, edit the BUILD.COM file and change
X`09   the line with the CC command for JOBLOG.C to look like
X
X`09   $ cc/optimize=inline/define=PHOTO_MODE
X
X   2.  Build the executable:
X
X`09a) If you have MMS installed on your system, enter
X
X`09`09$ MMS
X
X`09b) If you don't have MMS installed, enter
X
X`09`09$ @BUILD
X
X`09There are some free versions of MAKE available for VMS that might
X`09work with the DESCRIP.MMS file, although I've never tried any.
X
X   3.  Copy JOBLOG.EXE to it's final destination.  SYS$SYSTEM is a reasonabl
Ve
X       location for most systems and will be used in the following example
X       steps.  If your final destination is different, be sure to substitute
X       wherever SYS$SYSTEM is used below.
X
X   NOTE:  Steps 3-8 are not required for PHOTO mode.
X
X   4.  Install JOBLOG using the INSTALL program.  Enter
X
X`09$ INSTALL
X
X       and at the INSTALL> prompt enter
X
X       INSTALL> ADD SYS$SYSTEM:JOBLOG.EXE/OPEN/HEADER/SHARE/PRIV=(SYSPRV,CMK
VRNL)
X
X       Arrange for JOBLOG to be INSTALLed at system boot time by adding the
V line
X       from step #3 to the appropriate startup file.
X
X   5.  Add a symbol definition to SYS$SYSTEM:SYLOGIN.COM for JOBLOG.  For
X       example,
X
X`09$ JOBLOG :== $JOBLOG
X
X       would work if JOBLOG is installed in SYS$SYSTEM.  If it isn't, you'll
X       have to use the full file specification.
X
X   6.  Add the help file to the system help library.  To do this, you must
X       have exclusive access to SYS$HELP:HELPLIB.HLB.  An ideal time would b
Ve
X       when you have the machine to yourself and logins are disabled.  If
X       you're installing JOBLOG for the first time, the command for adding
X       the help library is
X
X`09$ LIBRARY/HELP/INSERT SYS$HELP:HELPLIB.HLB JOBLOG.HLP
X
X       If JOBLOG's help file already exists in your help library, the comman
Vd
X       would be
X
X`09$ LIBRARY/HELP/REPLACE SYS$HELP:HELPLIB.HLB JOBLOG.HLP
X
X       If you don't have the system to yourself, you can:
X
X          1) Protect SYS$HELP:HELPLIB.HLB so that no one can access it, wait
X`09     until everyone is done using it, insert the help file, and reset
X`09     the protection back to what it was when you started.  A few
X`09     people might get protection failures when running HELP but it
X`09     beats shutting down your machine.
X`20
X`09  2) Copy SYS$HELP:HELPLIB.HLB to your own area, do the update, and
X`09     copy it back to SYS$HELPLIB.HLB;n+1.  Make sure the file pro-
X`09     tection is correct and verify that the new help library is
X`09     correct.  Purge the file later at your convenience.
X
X   7.  Create the two directories required for JOBLOG:
X
X`09- a directory where log files live while the user is running JOBLOG;
X`09  after a user exits JOBLOG, their log file will be 1) moved to
X`09  another location (the user's area or the staging area) or 2) de-
X`09  leted, either by the user or after printing.
X
X`09  Example:  SYS$SYSTEM:`5BJOBLOG_LOG`5D
X
X`09- a "staging" directory where log files live waiting to be picked up
X`09  by the recipient specified by the user.
X
X`09  Example:  SYS$SYSTEM:`5BJOBLOG_STAGE`5D
X
X       IMPORTANT:  Both directories should be protected RWED,,,
X
X   8.  Create two system-wide logical names pointing to the directories
X       created in step #6.  The logical names are
X
X`09JOBLOG$LOG
X`09JOBLOG$STAGE
X
X       Define them as follows:
X
X`09$ DEFINE/SYSTEM/EXEC/TRANS=CONCEALED JOBLOG$LOG SYS$SYSTEM:`5BJOBLOG_LOG`
V5D
X`09$ DEFINE/SYSTEM/EXEC/TRANS=CONCEALED JOBLOG$STAGE SYS$SYSTEM:`5BJOBLOG_ST
VAGE`5D
X
X       Arrange for these logicals to be defined at system boot time by addin
Vg
X       the above definitions to the appropriate startup file.
X
X   9.  Add an entry into a batch job that runs once per day that will check
X       the staging directory for old log files and notify the sender and
X       recipient that they haven't been picked up.
X
X`09Example:  $ JOBLOG/SKIM/WAIT=10/WARN=7
X
X   That should do it.  Try running it and see if it works.  If you have pro-
Xblems building/installing JOBLOG, feel free to call me or send me e-mail and
Xlet me know how I blew it.  I'll do what I can to make sure that it can be
Xinstalled at your site.
X
XHACKING ON THE CODE
X   Since the source is distributed, feel free to hack on the code.  There is
Xnothing very complicated in JOBLOG; the code itself is pretty straightforwar
Vd
X(at least I think so! :`5E).  If you find a bug, you can either 1) fix it yo
Vur-
Xself, contact me, and send me the fix, or 2) let me know about it and I'll s
Vee
Xwhat I can do.  I'll be sending out patches when appropriate.
X
XA NOTE ABOUT VMS 5.4
X   VMS 5.4 includes a new PTY driver, FTDRIVER, that will replace the TW/PY
Xdrivers.  Once we get 5.4 installed here (which should be soon), I'll be
Xporting JOBLOG to work with the new device driver.  Thus, there will be two
Xversions but each will contain the same features.  The only differences will
Xbe the interaction with the respective PTY driver.  Once the port is com-
Xplete, I'll post the new version.
X
XCONCLUSION
X   I put a lot of work into JOBLOG and I would appreciate any comments/
Xsuggestions/flames that you might have.  If you get it up and running, I
Xwould appreciate it if you would either send me e-mail or phone me, letting
Xme know that you installed it and what your thoughts are about it.
X--
XLeonard Peirce                  Internet:  peirce@gumby.cc.wmich.edu
XWestern Michigan University                peirce@gw.wmich.edu
XAcademic Computing Services     UUCP:      ...!uunet!sharkey!wmichgw!peirce
XKalamazoo, MI  49008            Voice:     (616) 387-5469
$ CALL UNPACK [.JOBLOG]README.TXT;1 1614496398
$ create 'f'
X/***************************************************************************
V****
X****************************************************************************
V****
X
X   Installation:  Western Michigan University Academic Computing Services
X
X   System:`09General Purpose Subroutines
X `20
X   Program:`09JOBLOG
X
X   Version=01`09Level=00`0909/12/90`09Leonard J. Peirce
X
X   Purpose:`09Three general purpose subroutines used by JOBLOG.  If you
X`09`09want to use them for something else, feel free.  I just
X`09`09didn't want to include them in JOBLOG.C since they already
X`09`09exist in a object library here.
X
X   Version=01`09Level=01`0901/18/91`09Leonard J. Peirce
X
X   Purpose:`09Add strmcpy, str_pref_trim(), and str_post_trim().
X
X   Arguments:`09See individual routines
X
X   External variables:`09none
X
X   WMU external functions:
X
X          Defined:`09cat,strins,strlu,strmcpy,str_post_trim,str_pref_trim
X
X          Called:`09none
X
X   Files accessed:`09none
X
X   Return codes:`09See individual routines
X
X   Compiling instructions:`09See DESCRIP.MMS
X
X   Linking instructions:`09See DESCRIP.MMS
X
X   Other information:`09`09Copyright (c) 1990, Leonard J. Peirce
X
X****************************************************************************
V****
X****************************************************************************
V***/
X
X/***************************************************************************
V***/
X/*
V                                                                         `20
V  */
X/*                        # I N C L U D E   F I L E S
V                         */
X/*
V                                                                         `20
V  */
X/***************************************************************************
V***/
X
X#include varargs
X#include ctype
X
X/***************************************************************************
V***/
X/*
V                                                                         `20
V  */
X/*                             # D E F I N E S
V                                */
X/*
V                                                                         `20
V  */
X/***************************************************************************
V***/
X
X/***************************************************************************
V***/
X/*
V                                                                         `20
V  */
X/*          S T R U C T U R E S ,   U N I O N S ,   T Y P E D E F S
V           */
X/*
V                                                                         `20
V  */
X/***************************************************************************
V***/
X
X/***************************************************************************
V***/
X/*
V                                                                         `20
V  */
X/*   E X T E R N A L   D E F I N I T I O N S   &   D E C L A R A T I O N S
V    */
X/*
V                                                                         `20
V  */
X/***************************************************************************
V***/
X
X`09 char`09  *cat(),
X`09`09  *str_pref_trim(),
X`09`09  *str_post_trim(),
X`09`09  *strmcpy();
X
X`09 int`09  strins();
X
X`09 void`09  strlu();
X
X/***************************************************************************
V***/
X/*
V                                                                         `20
V  */
X/*     S T A T I C   D E F I N I T I O N S   &   D E C L A R A T I O N S
V      */
X/*
V                                                                         `20
V  */
X/***************************************************************************
V***/
X`0C
X/***************************************************************************
V****
X****************************************************************************
V****
X
X  Function:`09cat
X
X  Purpose:`09This general-purpose subroutine will concatenate null-
X`09`09terminated strings into one destination string.
X
X  Formal Parameters:
X
X`09Name`09`09`09Description
X`09----`09`09`09-----------
X`09dest`09`09`09where new string is created
X`09source1,...sourcen`09input strings
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`09retval`09`09`09pointer to destination string
X`09nullptr`09`09`09null string pointer; returned when
X`09`09`09`09no arguments are passed
X
X****************************************************************************
V****
X****************************************************************************
V***/
X
Xchar *cat(va_alist)
X`09`09`09`09`09/*******   FORMAL  PARAMETERS   *******/
X`09 va_dcl`09`09`09`09/* variable-length parameter list     */
X
X`7B`09/*** cat ***/
X`09`09`09`09`09/********   LOCAL  VARIABLES   ********/
Xregister char`09  *dest,`09`09/* pointer to destination string      */
X`09`09  *source;`09`09/* pointer to current source string   */
X`09 char`09  *retval;`09`09/* to save pointer to destination     */
Xregister int`09  count;`09`09/* number of arguments passed`09      */
X`09 va_list  incrmtr;`09`09/* argument list incrementor`09      */
Xstatic`09 char`09  *nullptr = "";`09/* null string pointer`09`09      */
X
X
X   va_start(incrmtr);`09`09`09/* begin everything....`09`09      */
X
X   va_count(count);`09`09`09/* get number of arguments`09      */
X
X   if(count == 0)`09`09`09/* were any arguments specified?      */
X      return(nullptr);`09`09`09/* nope, get out of here...`09      */
X
X   dest = va_arg(incrmtr,char*);`09/* get the destination pointer`09      */
X   retval = dest;`09`09`09/* save pointer to destination`09      */
X
X   source = va_arg(incrmtr,char*);`09/* get the first source pointer`09
V      */
X
X   while(--count > 0)`09`09`09/* process all of the source strings  */
X   `7B
X      while(*dest++ = *source++)`09/* cat the source to the destination  */
X`09 ;
X
X      dest--;`09`09`09`09/* back over the null character`09      */
X      source = va_arg(incrmtr,char*);`09/* get the next argument`09      */
X   `7D
X
X   *dest = '\0';`09`09`09/* terminate the destination`09      */
X   va_end(incrmtr);`09`09`09/* end varargs session`09`09      */
X
X   return(retval);`09`09`09/* return pointer to destination      */
X
X`7D`09/*** cat ***/
X`0C
X/***************************************************************************
V****
X****************************************************************************
V****
X
X  Function:`09strins
X
X  Purpose:`09Insert a character string into another at a specified
X`09`09position.
X
X  Formal Parameters:
X
X`09Name`09`09`09Description
X`09----`09`09`09-----------
X`09str`09`09`09string to be updated; should be large
X`09`09`09`09enough to accomodate the new string
X`09new`09`09`09string to be inserted
X`09position`09`09place to insert new into str
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`09  0`09`09`09string insert successful
X`09 -1`09`09`09unable to insert string because position
X`09`09`09`09points outside of str
X
X****************************************************************************
V****
X****************************************************************************
V***/
X
Xint strins(str,new,position)
X
Xregister char`09  *str,
X`09`09  *new;
Xregister int`09  position;
X
X`7B`09/*** strins ***/
X`09`09`09`09`09/********   LOCAL  VARIABLES   ********/
Xregister int`09  i,`09`09`09/* loop and array index`09`09      */
X`09`09  j;`09`09`09/* temporary variable`09`09      */
X`09 int`09  new_len,`09`09/* length of string to insert`09      */
X`09`09  str_len;`09`09/* length of str`09`09      */
X
X
X   str_len = strlen(str);`09`09/* get length of current str`09      */
X
X   if((position > str_len) `7C`7C (position < 0))
X      i = -1;
X   else
X   `7B
X      new_len = strlen(new);`09`09/* get length of string to insert     */
X      i = new_len + str_len - 1;`09/* get where to start when we shift   */
X      *(str+i+1) = '\0'; `09`09/* terminate it first `09`09      */
X      j = str_len - 1;`09`09`09/* point to last char of str`09      */
X
X      /* now shift everything over to make room for the new string */
X
X      while(j >= position)
X      `7B
X`09 *(str+i) = *(str+j);
X`09 --i;
X`09 --j;
X      `7D
X
X      /* now add the new string in the right slot */
X
X      for(i = 0,j = position; *(new+i) != '\0'; i++,j++)
X         *(str+j) = *(new+i);     `20
X
X      i = 0;
X   `7D
X
X   return(i);
X
X`7D`09/*** strins ***/     `20
X`0C
X/***************************************************************************
V****
X****************************************************************************
V****
X
X  Function:`09strlu
X
X  Purpose:`09Convert all lower-case characters in a string to upper-case.
X
X  Formal Parameters:
X
X`09Name`09`09`09Description
X`09----`09`09`09-----------
X`09source`09`09`09source string to be converted
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
Xvoid strlu(source)
X
Xregister char`09  *source;
X
X`7B`09/*** strlu ***/
X
X   while(*source)
X   `7B
X      *source = _toupper(*source);
X      source++;
X   `7D
X
X   return;
X
X`7D`09/*** strlu ***/
X`0C
X/***************************************************************************
V****
X****************************************************************************
V****
X
X  Function:`09strmcpy
X
X  Purpose:`09Copy at most m characters into the target string.  The
X`09`09resultant string is guaranteed to be null-terminated.
X`09`09This provides an alternative to strncpy() which does not
X`09`09guarantee that strings are null-terminated.
X
X  Formal Parameters:
X
X`09Name`09`09`09Description
X`09----`09`09`09-----------
X`09dest`09`09`09where new string is written
X`09source`09`09`09source for copy
X`09max`09`09`09maximum number of bytes to copy
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
Xchar *strmcpy(dest,source,max)
Xregister char`09  *dest,
X`09`09  *source;
Xregister int`09  max;
X
X`7B`09/*** strmcpy ***/
X`09`09`09`09`09/********   LOCAL  VARIABLES   ********/
Xregister int`09  i;`09`09`09/* loop and array index`09`09      */
X
X   for(i = 0;i < max && *(source+i); i++)
X      *(dest+i) = *(source+i);
X
X   *(dest+i) = '\0';`09`09`09/* terminate the destination string   */
X
X   return(dest);
X
X`7D`09/*** strmcpy ***/
X`0C
X/***************************************************************************
V****
X****************************************************************************
V****
X
X  Function:`09str_pref_trim
X
X  Purpose:`09Strip out leading whitespace from a string
X
X  Formal Parameters:
X
X`09Name`09`09`09Description
X`09----`09`09`09-----------
X`09str`09`09`09string to be stripped
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`09str
X
X****************************************************************************
V****
X****************************************************************************
V***/
X
Xchar *str_pref_trim(str)
X`09`09`09`09`09/*******   FORMAL  PARAMETERS   *******/
Xregister char`09  *str;`09`09`09/* string to be trim`09`09      */
X
X`7B`09/*** str_pref_trim ***/
X`09`09`09`09`09/********   LOCAL  VARIABLES   ********/
Xregister char`09  *ptr;`09`09`09/* temporary pointer`09`09      */
X
X
X   ptr = str;
X
X   while(isspace(*ptr))`09`09`09/* skip the leading whitespace first  */
X      ++ptr;
X
X   while(*ptr)
X      *ptr++ = *str++;
X
X   *str = '\0';`09`09`09`09/* make sure it's a string`09      */
X   return(str);
X
X`7D`09/*** str_pref_trim ***/
X`0C
X/***************************************************************************
V****
X****************************************************************************
V****
X
X  Function:`09str_post_trim
X
X  Purpose:`09Strip out trailing whitespace from a string
X
X  Formal Parameters:
X
X`09Name`09`09`09Description
X`09----`09`09`09-----------
X`09str`09`09`09string to be stripped
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`09str
X
X****************************************************************************
V****
X****************************************************************************
V***/
X
Xchar *str_post_trim(str)
X`09`09`09`09`09/*******   FORMAL  PARAMETERS   *******/
Xregister char`09  *str;`09`09`09/* string to be trim`09`09      */
X
X`7B`09/*** str_post_trim ***/
X`09`09`09`09`09/********   LOCAL  VARIABLES   ********/
Xregister char`09  *ptr;`09`09`09/* temporary pointer`09`09      */
X
X
X   ptr = &str`5Bstrlen(str) - 1`5D;
X
X   while(isspace(*ptr))`09`09`09/* find first non-whitespace char     */
X      --ptr;
X
X   *(ptr + 1) = '\0';`09`09`09/* chop off the whitespace characters */
X   return(str);
X
X`7D`09/*** str_post_trim ***/
X
$ CALL UNPACK [.JOBLOG]SUBS.C;1 2015128443
$ v=f$verify(v)
$ EXIT
