#!/bin/sh
## Usage: In "firstaction" or "prerotate" block of logrotate's conf;
##   prerotacopy -n ROTATE_COUNT [-a] [-z] -o DEST_DIR ${1+"$@"}
## Important: Handled logfile must be logrotate'd with "nodateext".
##
## -n ROTATE_COUNT
##     Mandatory. ROTATE_COUNT should be;
##     [in conjunction with "firstaction"]
##       Equal to logrotate's "rotate" count
##     [in conjunction with "prerotate"]
##       Equal to logrotate's "rotate" count (logrotate=3.7.1)
##       "rotate" count + 1 (logrotate>=3.7.4)
## -o DEST_DIR
##     Mandatory. Target file will be copied into DEST_DIR with
##     name "BASENAME-YYYYmmddHH", where YYYYmmddHH is mod-time
##     of the source file. (see also -a)
## -a
##     Auto-parent. Destination becomes subdirectory on top of
##     DEST_DIR. Its name is that of parent directory of the
##     source. Subdirectory will be made if absent, but lack of
##     DEST_DIR always produces error.
## -z
##     File will be 'gzip'ed to the destination.
##
function sym2mod () {
  ls -l $1 |awk '
    {
      if ($1 ~ /^l/) exit 1

      sub(/d/, "", $1);
      u = substr($1, 1, 3);
      gsub(/-/, "", u);
      sub(/s/, "xs", u);
      sub(/S/, "s", u);
      g = substr($1, 4, 3);
      gsub(/-/, "", g);
      sub(/s/, "xs", g);
      sub(/S/, "s", g);
      o = substr($1, 7);
      gsub(/-/, "", o);
      sub(/t/, "xt", o);
      sub(/T/, "t", o);
    }
    { printf "u=%s,g=%s,o=%s\n", u, g, o }
  '
  return $?
}

AUTOP=0
COMPRESS=0

#debug
#echo "$*" >/tmp/$(basename $0).out

while getopts "n:o:az" opt; do
    case $opt in
      n)
        GEN=$OPTARG;;
      o)
        OUTDIR=$OPTARG;;
      a)
        AUTOP=1;;
      z)
        COMPRESS=1;;
    esac
done
shift $((OPTIND - 1))

if [ "x$GEN" = "x" -o "x$OUTDIR" = "x" ]; then
    exit 1
fi

if [ "$GEN" = "0" ]; then
    GEN=""
else
    GEN=".$GEN"
fi

# Let's do it. Target files passed by logrotate can become a list of list when
# they are specified with wildcards in logrotate conf, so they must be dealt
# with like two dimension array.
OUTDIR_ORG=$OUTDIR
for V in $*; do
    for F in $V; do
	#debug
	#ls -l $(dirname $F) >>/tmp/$(basename $0).out

	if [ -f $F$GEN ]; then
	    OUTDIR=$OUTDIR_ORG
	    [ -d $OUTDIR ] || exit 1
	    EXT=$(stat $F$GEN |grep ^Modify |cut -d' ' -f2-3 |cut -d':' -f1 |tr -d '[[:blank:]-]')

	    if [ $AUTOP -eq 1 ]; then
		PDIR=$(dirname $F)
		OUTDIR=${OUTDIR}/${PDIR##*/}
		if [ ! -e "$OUTDIR" ]; then
		    mkdir $OUTDIR &>/dev/null || continue
		fi
	    fi

	    #debug
	    #echo "F.GEN:$F$GEN, OUTFILE:${OUTDIR}/$(basename $F)-$EXT" >>/tmp/$(basename $0).out

	    if [ $COMPRESS -eq 1 ]; then
		OUTFILE=${OUTDIR}/$(basename $F)-${EXT}.gz
		gzip -9qc $F$GEN >$OUTFILE &&
		 chmod $(sym2mod $F$GEN) $OUTFILE &>/dev/null || :
	    else
		cp -pf $F$GEN ${OUTDIR}/$(basename $F)-$EXT || :
	    fi
	fi
    done
done
