#! /bin/bash

export_ko="kernel_log_dev"
max_num=0
valid_keep_old_logs=0
max_old_logs=999999
min_num=${max_old_logs}

. /etc/log_redirect/config

function get_major()
{
    local dev_name="$1"
    echo `cat /proc/devices | grep "$dev_name" | awk '{print $1}'`
}

function mk_char_dev()
{
    local char_dev="$1"
    local maj=$2
    mknod "$char_dev"  c  $maj  0 -m 0600
    [  $? -eq 0 ] || { echo "export_log_dev: mknod $1 failed." ; return 1; }
}

function load_driver()
{
    local module="/lib/modules/FusionOS/kernel_log/${export_ko}.ko"

    if [ ! -f "$module" ]
    then
        echo "${export_ko}.ko not found in system."
        return 1
    fi

    insmod  "$module"
    if [ $? -ne 0 ]
    then
         echo "export_log_dev: insmod $export_ko fail."
         return 1
    fi

    log_maj=$(get_major "${export_ko}")
    [ "x$log_maj" = "x" ] && { echo "export_log_dev: get major number of ${export_ko} failed."; return 1; }
    mk_char_dev  "/dev/${export_ko}"    "$log_maj"
    return $?
}

function stop_nvram()
{
    [ -n "`cat /proc/devices | grep ${export_ko}`" ] && rmmod ${export_ko}.ko
    [ -c /dev/${export_ko} ] && rm /dev/${export_ko}

    return 0
}

function is_driver_loaded()
{
    printk_driver=`lsmod | grep "${export_ko}"`
    if [ -n "$printk_driver" ]
    then
        return 1
    fi
    return 0
}

function is_valid_kernel_log_dir()
{
    local file="$1"
    #must be a directory
    if [ ! -d "${export_path}/$file" ]
    then
        return 1
    fi

    #must at least be 6-bits integer
    if [ ! -n "$(echo $file | sed -n "/^[0-9]\{6,\}$/p")" ]
    then
        return 1
    fi

    if [ $file -eq 0 ]
    then
        return 1
    fi

    #if more than 6-bits, must not begin with zero
    if [ -n "$(echo $file | sed -n "/^0\{1,\}[0-9]\{6,\}$/p")" ]
    then
        return 1
    fi

    return 0
}

do_export_kernel_log ()
{
    local log_dir_list=()
    local log_num=0
    if [ "`ls $export_path`" ]
    then
        for file in `ls ${export_path} | sort -n`
        do
            is_valid_kernel_log_dir "$file"
            if [ $? -ne 0 ]
            then
                continue
            else
                log_dir_list[$log_num]="$file"
                log_num=$((log_num + 1))
                max_num="$file"
            fi
        done
    fi

    max_num=$((10#$max_num + 1))
    max_num=`printf "%06d" $max_num`
    #there may be user-created regular files
    while [ -f "${export_path}/${max_num}" ]
    do
        max_num=$((10#$max_num + 1))
        max_num=`printf "%06d" $max_num`
    done
    mkdir -p -m 750 ${export_path}/${max_num}
    log_dir_list[$log_num]="$max_num"

    #clean up old logs
    del_num=$((log_num - ${keep_old_logs} + 1))
    index=0
    while [ $del_num -gt 0 ]
    do
        min_num=${log_dir_list[index]}
        if [ -n "$min_num" -a -d "${export_path}/$min_num" ]
        then
            echo "delete ${export_path}/${min_num}"
            rm -rf "${export_path}/${min_num}"
            if [ $? -ne 0 ]
            then
                echo "delete file ${export_path}/${min_num} fail."
            fi
        fi
        index=$((index + 1))
        del_num=$((del_num - 1))
    done
    os_export_printk "${export_path}/${max_num}"
    return $?
}

export_kernel_log()
{
    if [ -z "$export_path" ]
    then
        echo "export path not enable."
        return 1
    fi
    if [ -z "`echo $export_path | grep ^/`" ]
    then
        echo "the path to export kernel must be absolute path."
        return 1
    fi
    if [ ! -d "$export_path" ]
    then
	echo "dir is not exit,so make config dir"
	mkdir -p $export_path
    fi
    if [ ! -w "$export_path" ]
    then
        echo "export path not writable or path not exist."
        return 1
    fi
    if [ ! -n "$keep_old_logs" ]
    then
        echo "keep_old_logs option in config file is empty!"
        return 1
    fi
    if [ ! -n "$(echo $keep_old_logs | sed -n "/^-*[0-9]\+$/p")" ]
    then
        echo "keep_old_logs option in config file is not an integer!"
        return 1
    fi
    if [ $keep_old_logs -ge 1 ] && [ $keep_old_logs -le $max_old_logs ]
    then
        valid_keep_old_logs=1
    fi
    if [ $valid_keep_old_logs -ne 1 ]
    then
        echo "keep_old_logs option in config file is invalid! the valid value is [1 ~ $max_old_logs]!."
        return 1
    fi
    do_export_kernel_log
    return $?
}

case "$1" in
    start)
        is_driver_loaded
        if [ $? -eq 0 ]
        then
            load_driver
            if [ $? -ne 0 ]
            then
                echo "load export driver failed."
                exit 1
            fi
        fi

        export_kernel_log
        if [ $? -eq 0 ]
        then
            echo "export kernel log success."
            exit 0
        else
            echo "export kernel log fail."
            exit 1
        fi
        ;;

    stop)
        stop_nvram
        echo "check kernel_log.service:  stopped"
        ;;

    restart)
        $0 stop
        $0 start
        ;;

    status)
        is_driver_loaded
        if [ $? -ne 0 ]
        then
            echo "check kernel_log.service: running"
        else
            echo "check kernel_log.service:  stopped"
        fi
        ;;
    *)
        echo "Usage: $0 {start|stop|restart|status}"
        exit 0
        ;;
esac

