#!/usr/bin/env bash
# vim: syntax=sh
#  Title        : ArtCom software regular system maintainance (called twice/day)
#  -------------------------------------------------------------------------
#                  This is an UNPUBLISHED work COPYRIGHT by
#		                  ArtCom GmbH
#                    Haferwende 2; D-28357 Bremen; Germany
#       It may be used, copied, or distributed only as permitted in a
#                              written license.
#  -------------------------------------------------------------------------
#  Created      :     Fri, 31-May-1991 / 11:32 / (rb,pf)
#  Version      : $Id: cleanup,v 1.72 2019-03-01 09:48:51 tm Exp $
#  Portability  : /bin/sh
#I Usage        : Wird von 'cron' z.B. 2 mal taeglich aufgerufen: 00:15 u. 12:15
#I Remarks      : Dieses Skript dient zur Automatisierung der Systemverwaltung,
#I		  beseitigt nicht mehr bentige Leichendateien und 
#I		  verkrzt diverse Logfiles.
#  -------------------------------------------------------------------------
#
$DBG_SH
#
CALLED_IN=`dirname $0` # bitslib/service
if [ -z "$CALLED_IN" ] || [ "$CALLED_IN" = "." ]
then CALLED_IN=`/bin/pwd`
fi

# Optionen abarbeiten :
VERBOSE=false
while [ "$1" ] ; do
    case "$1" in 
        --verbose) shift; VERBOSE=: ;;
	--customer) shift; export AC_CUSTOMER=$1; shift ;;
	--projects) shift; export AC_PROJECTS=$1; shift ;;
	--bitsdat) shift; export BITSDAT=$1; shift ;;
        *)         break ;;
    esac
done

if . `dirname $CALLED_IN`/bin/.ac-sh-funcs
then : fine
else echo "*** Error: unable to find $CALLED_IN/bin/.ac-sh-funcs" 1>&2
     exit 1
fi

# Logfiles might contain Non-ASCII characters not matching the System
# default encoding.  Avoid error messages due to encodings like UTF-8
# which provide only incomplete coverage of the possible value space.
# Use the C default locale, which should be available everywhere:
LC_ALL="C"
export LC_ALL

CFGFILE="$AC_CUSTOMER/logfiles"

#
# PROCEDURE Defend ();
#   Einige Sicherheitsmassnahmen, um eventuell denkbaren Problemen
#   durch fehlende Dateien und Verzeichnisse vorzubeugen :
Defend() {
    for DIR in "$AC_CUSTOMER" "$AC_PROJECTS" "$BITSDAT" "$TMP" \
    	       "$AC_PROJECTS/fonts"; do
        if [ -d "$DIR" ]
	then : fine
	else mkdir -p "$DIR" ; chmod 777 "$DIR"
	fi
    done
    for FILE in "$BITSDAT/jobs.log" "$BITSDAT/acwatchd.log"; do
        if [ -f "$FILE" ]
	then :
        else touch "$FILE" 
	     chmod 666 "$FILE"
	fi
    done
}
#
#
# PROCEDURE AssertConfigFile ();
AssertConfigFile() {
    if [ ! -f "$CFGFILE" ]
    then echo "# DEUTSCH:
#  Liste aller wachsenden System-Log-Dateien, die durch
#  das Skript /bitslib/service/cleanup regelmaessig verkuerzt werden,
#  damit sie nicht ueber alle Massen anwachsen und Plattenplatz verbrauchen.
#  Diese Datei hier hat folgendes Format : 
#    <Dateiname der Log-Datei> <maximale Laenge in Zeilen>
# ENGLISH:
#  Configuration of ArtCom logfile rotation: 
#  A list of ever growing software log files, which should be shortened
#  regulary to avoid mass consumption of disk space.  The file has the
#  following format
#    <filename> <maximum length in number of lines>" >"$CFGFILE"
    fi
    chmod 666 "$CFGFILE"
    # --- Vorhandene Konfigurationsdatei um allgemeine Logfiles ergaenzen : ---
    cat $CFGFILE "$BITSLIB/service/logfiles" > /tmp/bscl.$$
    # --- Doppelte schon vorhandene Eintraege eliminieren : ---
    $AWK '  /^#/ { print; next }
	   { if ($1 in alreadyseen) {
		 next
	     } else { 
		 print ; alreadyseen[$1] = 1; 
	     }
	   }' < /tmp/bscl.$$ > $CFGFILE
    rm -f /tmp/bscl.$$
}

CleanMountDir()
{
  while [ -n "$1" ]; do
      ( cd $1 || exit 1
	#--- briggebliebene Mountpoints
	rmdir *
	#--- "dangling" Symlinks
	gfind . -xtype l -print | while read x; do rm -f $x; done
      ) 2>/dev/null
      shift
  done
} # CleanMountDir

CustomerBackup() {
    if [ -z "$AC_CUSTOMER_BACKUPDIR" ]
    then AC_CUSTOMER_BACKUPDIR="$AC_PROJECTS"
    fi
    # Preserve seven additional versions for additional safety:
    BACKUP=$AC_CUSTOMER_BACKUPDIR/customer~7.tgz
    for NEW in $AC_CUSTOMER_BACKUPDIR/customer~6.tgz \
               $AC_CUSTOMER_BACKUPDIR/customer~5.tgz \
               $AC_CUSTOMER_BACKUPDIR/customer~4.tgz \
               $AC_CUSTOMER_BACKUPDIR/customer~3.tgz \
               $AC_CUSTOMER_BACKUPDIR/customer~2.tgz \
               $AC_CUSTOMER_BACKUPDIR/customer~1.tgz \
	       $AC_CUSTOMER_BACKUPDIR/customer.tgz; do
	if [ -r $NEW ]
	then mv $NEW $BACKUP
	fi
	BACKUP=$NEW
    done
    if CheckFlag OLD_STYLE_CUSTOMER_BACKUPS
    then AC_CUSTOMER_WITHOUT_SLASH=`echo "$AC_CUSTOMER" | sed 's|^/||'`
	 ( cd / ; tar chf - "$AC_CUSTOMER_WITHOUT_SLASH" \
	   | gzip > "$AC_CUSTOMER_BACKUPDIR/customer.tgz" )
    else ( cd $AC_CUSTOMER && tar cf - . \
           | gzip > "$AC_CUSTOMER_BACKUPDIR/customer.tgz" )
    fi
    chmod 444 "$AC_CUSTOMER_BACKUPDIR/customer.tgz"
}
#
TruncateLogfile() {
    LOGFILE="$1"
    LINELIM="$2"
    if $VERBOSE
    then echo "$LOGFILE --> $LINELIM Zeilen/Lines..."
    fi
    # --- Wieviel Zeilen sind drin : ---
    LINES=`wc "$LOGFILE" | $AWK '{print $1}'`
    # --- Abschneiden, falls zuviele : ---
    if   [ $LINES -gt $LINELIM ] 
    then $AWK '{ count = count + 1;
		 if ( count > lim ) print $0
	       }' lim=`expr $LINES - $LINELIM` < "$LOGFILE" > /tmp/tmp.$$ \
	 && cat /tmp/tmp.$$ > "$LOGFILE" || cat </dev/null >"$LOGFILE"
	 # Das folgende geht leider nicht, da tail mit groesseren Zeilenzahlen
	 # Probleme hat.  Offenbar ist ein interner Puffer zu klein :
	 # tail -$LINELIM < $LOGFILE > /tmp/tmp.$$ && cat /tmp/tmp.$$ > $LOGFILE
	 rm -f /tmp/tmp.$$
    fi
}
#
StartStatistics() {
    # TODO $BITSDAT/starts.log auswerten und eventuell 
    # $BITSDAT/defaultuser ndern
    :
    DH=`date +%w-%k` # %w day of week, tuesday = 2, %k hour ' 0'..'23'
    # Tuesday 0:15 run == "2- 0"
    if [ "$DH" = "2- 0" ] && CheckFlag DIAGNOSTIC_MAIL
    then if [ -r "$AC_CUSTOMER/DIAGNOSTIC_MAIL" ]
         then COMPANY_NAME=`cat "$AC_CUSTOMER/DIAGNOSTIC_MAIL"`
	 fi
         send_crash_reports "$COMPANY_NAME"
    fi
}
# -- http://problems/issue6996 : Cleanup files left over by MacOS visitors in
#    directory $AC_PROJECTS/autofolder
CleanAutofolders() {
    # TODO: Should make sure $AC_PROJECTS/autofolder is local and accessible
    find ${AC_PROJECTS}/autofolder -type f -name ._\* -print0 \
         | xargs --null rm -f 2>/dev/null
}
#
# === MAIN PART starts here : ==========================================
Defend
# --- remove old orphaned .pid files left over by malfunctioned termination handlers: ---
${BITSLIB}/bin/stopArtCom -q --sanity-check-only
if [ -n "$AC_NO_DAEMONS" ]
then if $VERBOSE
     then echo "cleanup only on the main employer server and not here" >&2
     fi
     # -- Kein logrote auf dem Worker, weil BITSDAT geshart ist.
     rm -f /etc/logrotate.d/artcom
     exit 0
fi
CustomerBackup

#
# --- Die uebrigen (normalen text) logfiles kuerzen : ---
if hash logrotate 2>/dev/null && configure_logrotate
then if $VERBOSE
     then echo "Using 'logrotate' to truncate the log files configured in /etc/logrotate.d/artcom"
     fi
     rm -f "$CFGFILE"
else AssertConfigFile
     $AWK '! /^ *#|^$/ { print $1 ; print $2 }' < "$CFGFILE" \
| while read LOGFILE && [ "$LOGFILE" ] ; do
	 read LINELIM
	 LOGFILES=`eval echo "$LOGFILE"`
	 for LOGFILE in $LOGFILES ; do
	     if [ -f "$LOGFILE" ]
	     then TruncateLogfile "$LOGFILE" "$LINELIM"
	     elif $VERBOSE
	     then echo "Skipping entry $LOGFILE. Doesn't exist." 1>&2
	     fi
	 done
     done 
fi
# --- JBoss macht sein eigenes tgliches logfile rolling.  Dennoch
#     wollen wir sehr alte (lter als 90 Tage) Logfiles entfernen:
if [ -z "$AC_JBOSSLOGDIRS" ]
then AC_JBOSSLOGDIRS="/opt/jboss/server/default/log"
     AC_JBOSSLOGDIRS="$AC_JBOSSLOGDIRS /opt/jboss-as7/standalone/log"
     AC_JBOSSLOGDIRS="$AC_JBOSSLOGDIRS /opt/wildfly/standalone/log"
fi
for JBOSSLOGDIR in $AC_JBOSSLOGDIRS ; do
    if [ -d "$JBOSSLOGDIR" ]
    then find "$JBOSSLOGDIR" -mtime +31 \
              -type f -name "server.log.*" -print0 | xargs -0 rm -f
    fi
done
# --- Auch alte Zeitschtzungsdateien eliminieren :
if [ -d ${BITSDAT} ]
then find ${BITSDAT} -name "JSTATUS.*" -type f -mtime +30 -print\
   | xargs rm -f 2>/dev/null
fi
# --- Auch alte SCipc-Named pipes eliminieren :
if [ -d ${BITSDAT}/scipc ]
then find ${BITSDAT}/scipc -atime +7 -type p -print \
   | egrep -v ".*\.(L|H)$" | xargs rm -f 2>/dev/null
fi
# --- Auch alte backtrace Dateien eliminieren :
if [ -d ${BITSDAT}/backtraces ]
then find ${BITSDAT}/backtraces -mtime +90 -type f -name "*.bt" -print \
   | xargs rm -f 2>/dev/null
fi
if [ -d ${BITSDAT}/backtraces.java ]
then find ${BITSDAT}/backtraces.java -mtime +90 -type f -print \
   | xargs rm -f 2>/dev/null
fi
# --- Auch alte Gravurlogs (LaserControl) eliminieren :
if [ -d ${BITSDAT}/engravings ]
then find ${BITSDAT}/engravings -mtime +31 -type f -print \
   | xargs rm -f 2>/dev/null
fi
# --- Auch alte Debugimages (LaserControl) eliminieren :
if [ -d ${TMP}/lasercontrol.debug ]
then find ${TMP}/lasercontrol.debug -mtime +14 -type f -print \
   | xargs rm -f 2>/dev/null
fi
# --- briggebliebene Kommandoskripte beseitigen
(find $TMP/scripts -type d -name "archivecmds*" -mtime +3 -print \
   | xargs rm -rf) 2>/dev/null
# --- Eventuell brig gebliebene alte Temporr-Bilder lschen :
find $TMP -mtime +1 -type f -name 'a*ppm' -print \
   | xargs rm -f 2>/dev/null
# --- Eventuell brig gebliebene alte Bitmap-Listendateien lschen :
find $TMP -mtime +5 -type f -name 'BITMAPLIST_*' -print \
   | xargs rm -f 2>/dev/null
# -- Alte Protokolle des Flexo-Gravurfrontends lschen :
if [ -d "$AC_PROJECTS/flexdat" ]
then find "$AC_PROJECTS/flexdat/engines" -mtime +7 -type f \
          -name 'receive*.log' -print0 | xargs --null rm -f 2>/dev/null
     find "$AC_PROJECTS/flexdat/engines" -mtime +7 -type f \
          -name 'send*.log' -print0 | xargs --null rm -f 2>/dev/null
fi
# -- Alte Temporrdaten des Embossing Managers lschen :
if [ -d "$AC_PROJECTS/embossing/rolls" ]
then find "$AC_PROJECTS/embossing/rolls" -mtime +7 -type f \
          -path '*/tmp/*' -print0 | xargs --null rm -f 2>/dev/null
fi
CleanAutofolders
# -- Cache mit ICC-Profilen fr die Transformation von Sonderfarben aufraeumen: 
if [ -d "$BITSDAT/cache/profiles/spotcolors" ]
then find "$BITSDAT/cache/profiles/spotcolors" -mtime +30 -type f \
          -name '*.icc' -print0 | xargs --null rm -f 2>/dev/null
fi
# --- ArtCom starts statistic: ---
StartStatistics
# --- remove other old temporary stuff left over by ArtCom programs: ---
for DIR in "$TMP" "${BITSDAT}/tmp"; do
    gfind "$DIR" -mtime +2 \( -name 'ArtCom*' -o -name 'T[0-9]*' \) -print0 \
       | xargs --null rm -rf 2>/dev/null
done
# --- Leeren des Bookletcaches unter eine bestimmte Gre
${BITSLIB}/bin/cacheDirCleanup
# --- Flag-files unter /customer lschen, die das Lschen von tmp-Files verhindern
rm -f "$AC_CUSTOMER/BITMAP_BOOKLET_KEEP_TEMPFILES" "$AC_CUSTOMER/PPN_KEEP_TEMPFILES" 2>/dev/null
# --- /etc/wtmp kuerzen (Das ist kein Textfile, so dass dafuer ein
#     gesondertes Programm 'fwtmp' benoetigt wird) :
case "$OS" in
    XENIX) FWTMP=${BITSLIB}/service/fwtmp;;
    *)     FWTMP=/usr/lib/acct/fwtmp;;
esac
if [ -x $FWTMP ]
then $FWTMP < /etc/wtmp | tail -2400 > /tmp/wtmp && \
	 $FWTMP -ic </tmp/wtmp > /etc/wtmp 
     rm -f /tmp/wtmp
fi
if   [ "$OS" = SunOS ]
then CleanMountDir /floppy /cdrom
fi
if $VERBOSE
then echo "Fertig. Done. Fin. Goed." 
fi
# --- EOF --- ;-) ---
