#!/bin/sh

CONF=/etc/tinyrot.conf
NEXTFILETOSEND=/var/local/log/nexttosendfile
LASTFILESENT=/tmp/lastsentfile

_DEVTYPE=/etc/sysconfig/devtypes
[ -f $_DEVTYPE ] && . $_DEVTYPE

_FEATURE=/etc/rc.d/features
[ -f $_FEATURE ] && . $_FEATURE
# -----------------------------------------------------------------------------
# functions
# -----------------------------------------------------------------------------

print_usage () {
    echo "showlog will print all available logs, including old rotated logs"
    echo "Usage:"
    echo "showlog [-f [logfile] | -o <outfile> [logfile] | -s ] "
    echo "    -f              follow log (tail -f)"
    echo "    -o <outfile>    cat all available logfile(s) to outfile (default: outfile=/dev/stdout)"
    echo "    -s              cat the zipped log files with special headers to pipe to the server"
    echo "      --full           sending all available logs"
    echo "      --fsn            sending logs non anonymously for Costumer Services"
    echo "    logfile         logfile to show (default: logfile=messages)"
    echo ""
    echo "NOTE: Don't use the full path. Just mention the file name"
    echo "Example: showlog messages"
    exit 1
}

print_stream_header () {
    NUMFILES=$1
    echo "MFBS/1.0 $NUMFILES"
    echo ""
}

print_gzip_header () {
    if [ -z $1 -o -z $2 ]; then
        echo "showlog: print_gzip_header: incorrect arguments"
        exit
    fi
    CONTENTLENGTH=$1
    CONTENTNAME=$2
    echo "Content-Length: $CONTENTLENGTH"
    echo "Content-Name: $CONTENTNAME"
    echo "Content-Type: GZIP"
    echo "Content-Encoding: GZIP"
    name=`productid`
    echo "X-DeviceType: `eval echo \\\${DEVTYPE_$name}`"
    echo "X-DeviceFirmwareVersion:`cat /etc/version.txt  | grep Version | awk '{print $4 }' | sed 's/\([0-9a-zA-Z]*\)-.*-\(.*\)/\2\1/'`"
}

print_gzip_header_dsn () {
    print_gzip_header $1 $2
    echo "X-DSN: `cat /proc/usid`"
    echo ""
}

print_gzip_header_anon () {
    print_gzip_header $1 $2
    echo "X-Anonymous-Tag: `cat /etc/guid`"
    echo ""
}

print_gzip_files_anon () {
    ALLFILES=$*
    for FILE in $ALLFILES
    do
        CONTENTNAME=$FILE
        CONTENTLENGTH=$(ls -l $FILE | awk '{print $5}')
        print_gzip_header_anon $CONTENTLENGTH $CONTENTNAME
        # NOTE: cat'ing raw gzip file
        cat $FILE
    done
}

print_gzip_files_dsn () {
    ALLFILES=$*
    for FILE in $ALLFILES
    do
        CONTENTNAME=$FILE
        CONTENTLENGTH=$(ls -l $FILE | awk '{print $5}')
        print_gzip_header_dsn $CONTENTLENGTH $CONTENTNAME
        # NOTE: cat'ing raw gzip file
        cat $FILE
    done
}

get_inode () {
    FILE=$1
    return `ls -i $FILE 2>/dev/null | awk '{print $1;}'`
}

wait_for_file() {
    FILE=$1
    while [ ! -f $FILE ]; do
        sleep 1
    done
}

follow_log () {
    LOG=$1

    while [ 1 ]; do
        wait_for_file $LOG
        tail -f $LOG &
        TAILPID=$!
        get_inode $LOG
        FILEINODE=$?
        while [ 1 ]; do
            get_inode $LOG
            NEWINODE=$?
            if [ $FILEINODE -ne $NEWINODE ]; then
                kill $TAILPID
                break
            fi

            sleep 1
        done
    done
}


on_term ()
{
    kill $TAILPID 2>/dev/null >/dev/null
    exit 0
}

# -----------------------------------------------------------------------------
# main
# -----------------------------------------------------------------------------

trap 'on_term' TERM INT EXIT

[ -f $CONF ] && . $CONF

if [ x$1 == "x--help" -o x$1 == "x-h" ]; then
    print_usage
    exit 1
fi

# -----------------------------------------------------------------------------
# parse args
# -----------------------------------------------------------------------------

OUTFILE=/dev/stdout
GZIP_HEADER_TYPE=print_gzip_files_anon
SENDING_GZIP=
SENDING_FULL=0
LOG="messages"
    
while [ "$1" != "" ]; do
    __ARG=
    case $1 in
        -f )
            if [ x$2 == "x" ]; then
                LOG="messages"
            else
                LOG=$2
            fi
            follow_log /var/log/$LOG
            # we dont come back here..
            exit
            ;;
        -o )
            shift
            if [ x$1 != "x" ]; then
                OUTFILE="$1"
            fi
            echo "" > $OUTFILE 2>/dev/null
            shift
            ;;
        -s )
            SENDING_GZIP=1
            shift
            ;;
        --full )
            SENDING_FULL=1
            shift
            ;;
        --fsn )
            GZIP_HEADER_TYPE=print_gzip_files_dsn
            shift
            ;;
        -h | --help )
            print_usage
            exit
            ;;
        * )
            LOG=$1
            ;;
    esac
    SHOWLOG_ARGS=$__ARGS
done


# -----------------------------------------------------------------------------
# calculate the number of files to send/show (NUMFILES) and their names
# (ALLFILES)
# -----------------------------------------------------------------------------
NUMFILES=0
ALLFILES=

# prevent tinyrot from starting after that point 
touch $FLAG_TINYROT_LOCK

# Not sending log to server (not coming from pipelog
if [ x$SENDING_GZIP == "x" ] ; then
    ALLFILES=`ls -1  $ARCHIVE_DIR/${LOG}_*.gz | xargs`
    if [ -n "$ALLFILES" ]; then
        zcat $ALLFILES >> $OUTFILE
    fi
    cat /var/log/$LOG >> $OUTFILE
else # coming from pipelog
    # Sending partial logs
    if [ x$SENDING_FULL == "x0" ] && [ -e $ARCHIVE_DIR/${LOG}_${OLDEST_FILE} ] ; then
        OLDEST_LZ=`cat $ARCHIVE_DIR/${LOG}_${OLDEST_FILE}`
    
        if [ -e $NEXTFILETOSEND ]; then
            OLDEST_LZ=`cat $NEXTFILETOSEND`
        fi

        YOUNGEST_LZ=`cat $ARCHIVE_DIR/${LOG}_${YOUNGEST_FILE}`
        COUNTER_LZ=$OLDEST_LZ

        OLDEST=`echo $OLDEST_LZ|sed 's/[0]*\(.*\)/\1/g'`
        YOUNGEST=`echo $YOUNGEST_LZ|sed 's/[0]*\(.*\)/\1/g'`
        COUNTER=`echo $COUNTER_LZ|sed 's/[0]*\(.*\)/\1/g'`
    

        while [ ${COUNTER} -lt ${YOUNGEST} ]; do
            FILE=$ARCHIVE_DIR/${LOG}_${COUNTER_LZ}_*.gz
            if [ -e $FILE ]; then
                ALLFILES="$ALLFILES $FILE"
                NUMFILES=$(($NUMFILES+1))
            fi
            COUNTER=$(($COUNTER+1))
            COUNTER_LZ=`echo $COUNTER | awk '{ printf "%08d", $1 }'`
        done
        # update LASTFILESENT
        if [ ${NUMFILES} -gt 0 ]; then
            echo $COUNTER | awk '{ printf "%08d", $1 }' > $LASTFILESENT
        else
            cat $NEXTFILETOSEND | awk '{ printf "%08d", $1 }' > $LASTFILESENT
        fi
        print_stream_header $NUMFILES  >> $OUTFILE
        $GZIP_HEADER_TYPE $ALLFILES  >> $OUTFILE
    else # Sending full logs
        print_stream_header  `ls $ARCHIVE_DIR/${LOG}_*.gz | wc -l ` >> $OUTFILE
        $GZIP_HEADER_TYPE `ls $ARCHIVE_DIR/${LOG}_*.gz | xargs ` >> $OUTFILE
    fi 
fi

#release tinyrot postponing thingy
rm -f $FLAG_TINYROT_LOCK

