Listing 1: Michael Chinni's "daily" script

#!/bin/ksh

# FILE:  daily
#
# PROGRAM:  daily
#
# DESCRIPTION:
#   Daily Accounting and File Roll-Out Program.
#
# OPTIONS:
#   None
#
# ARGUMENTS
#   None.
#
# EXIT CODES:
#   None
#
# ORIGINAL AUTHOR:
#   Michael J. Chinni <mchinni@pica.army.mil>
#
# HISTORY OF PROGRAM CHANGES:
#
#   DATE      VERSION  DONE BY   DESCRIPTION
#   --------  -------  --------  ----------------------------------------------
#   12/13/93   1.0.00  mchinni   Original release.
#

# Set PATH
PATH=/bin:/usr/5bin:/usr/bin:/usr/ucb:/usr/ccs/bin:/usr/mmdf:/local/bin
export PATH

# Set independent variables:
field1=""
field2=""
field3=""
field4=""
NULL="/dev/null"
PROG=`basename $0`  # name of this program
THISHOST=`hostname`  # name of this host

# Set dependent variables:
LIB="/local/lib/${PROG}"
DB=${LIB}/db
CMDS2BERUN=${LIB}/cmds_2_be_run

# Set dependent vars:
TMP=/tmp/${PROG}$$  # dir for temp files

# Create the dir for temp. files:
rm -rf ${TMP}
mkdir ${TMP}
chmod 0700 ${TMP}

# Set trap for signals:
trap '\
  EXITCODE=$? ; rm -rf ${TMP} ; echo "${PROG}:  Exiting" >&2 ; exit ${EXITCODE} \
    ' 01 02 03 04 05 15

#
# script operation is broken into 3 primary segments, with the work for each
# segment being done by a separate function. Functions are:
#   run_cmds  archive_data  cleanup_archive
#
# in addition to the 3 primary functions, there is one utility function:
#   set_fields
#

#
# RUN_CMDS
# ========
#
# execute CMDS2BERUN stdout>/dev/null stderr>${TMP}/cmds_report
# if there were any errors from cmds_2_be_run
# then
#   set subject of email message
#   send email to root using SUBJECT as a subject and ${TMP}/cmds_report as
#     the body of the message
# endif
#
run_cmds() {
  /bin/ksh ${CMDS2BERUN} 1>$NULL 2>${TMP}/cmds_report
  if [ -s ${TMP}/cmds_report ]
  then
    SUBJECT="${PROG}: ${THISHOST}: cmds error report"
    mail -s "${SUBJECT}" root < ${TMP}/cmds_report
  fi
}


#
# SET_FIELDS
# ==========
#
# "set_fields" is used as a utility function
#  it takes a single input line (i.e. $1) and parses it into global variables:
#   field1, field2, field3, and field4.
#

set_fields() {
  field1=`echo $1 | cut -f1 -d';'`
  field2=`echo $1 | cut -f2 -d';'`
  field3=`echo $1 | cut -f3 -d';'`
  field4=`echo $1 | cut -f4 -d';'`
}


#
# ARCHIVE_DATA
# ============
#
# while input still remains
# do
#   set CHAR1 to be the 1st character of the current line of input
#   parse fields from the current line of input
#   if the current line of input is not a comment and field1 is not empty
#   then
#     if field2 is a 'd' (file cp'd into a directory)
#     then
#       set today to be today's date in YYYMMDD format (using SysV date cmd.)
#       set archive_name to be ${field3}/${today} (path NOT division)
#       cp the file to be archived ($field3) to archive_name
#       chmod 644 archive_name
#       chgrp sys archive_name
#       null out the file to be archived
#     else (field2 is an 'f') (file cp'd over its archive)
#       cp the file to be archived on top of its archive
#       null out the file to be archived
#     fi
#   fi
# done
#

archive_data() {
  while read line
  do
    CHAR1=`echo ${line} | cut -c1`
    set_fields "${line}"
#   test if current line is blank or comment
    if [ "${CHAR1}" != "#" -a "${CHAR1}" != " " -a -n "${CHAR1}" -a \
      -n "${field1}" ]
    then
      if [ "${field2}" = "d" ]
      then
        today=`att date '+%Y%m%d'`
        archive_name="${field3}/${today}"
        cp ${field1} ${archive_name}
        chmod 644 ${archive_name}
        chgrp sys ${archive_name}
        cp ${NULL} ${field1}
      else
        cp ${field1} ${field3}
        cp ${NULL} ${field1}
      fi
    fi
  done
}


#
# CLEANUP_ARCHIVE
# ===============
#
# while input still remains
# do
#   set CHAR1 to be the 1st character of the current line of input
#   parse fields from the current line of input
#   if the current line of input is not a comment and field1 is not empty
#   then
#     cd $field3 (archive directory to be cleaned)
#     keep the 1st ${field4} files (based on time modified (latest 1st))
#     force the removal of any others
#   fi
# done
#

cleanup_archive()
{   while read line
  do
    CHAR1=`echo ${line} | cut -c1`
    set_fields "${line}"
#   test if current line is blank or comment
    if [ "${CHAR1}" != "#" -a "${CHAR1}" != " " -a -n "${CHAR1}" -a \
        "${field2}" = "d" ]
    then
      cd ${field3}
      let num=${field4}+1
      for file in `ls -t | grep -v '^\.' | tail +${num}`
      do
        rm -f "${file}"
      done
    fi
  done
}


#
# MAIN BODY
#

#
# Run standard 'daily' command file
run_cmds

#
# Archive data using daily/database (DB)
cat ${DB} | archive_data

#
# Clean up archive directory (keep the 1st field4 files)
cat ${DB} | cleanup_archive

#
# Done, so cleanup TMP
# cd to TMP and remove all files 
# cd to .. and remove TMP
cd ${TMP} && rm -f *
cd .. && rmdir ${TMP}


exit 0

