#!/bin/sh
#---------------------------------------------------------
# show_context.sh - script for managing/printing context files
#
# Copyright (c) 2000-2015, 2017, 2019 by cisco Systems, Inc.
#---------------------------------------------------------
coresubstitute()
{
    case $1 in
    e)  echo '.*';;
    p)  echo '[1-9][0-9]*';;
    s)  echo '[1-9][0-9]*';;
    t)  echo '[1-9][0-9-]*';;
    h)  echo '[^\.]*';;
    m)  echo '[0-9a-f]*';;
    *)  echo '.*';;
    esac
}

getcorearg()
{
    corepattern='%e_%p.by.%s.%t.%h.%m.core'
    corepattern=${corepattern##*/}
    if echo "$corepattern" | grep -q %$1; then
        substring=$corepattern
        substring=$(echo $substring | sed s/\\./\\\\./g)
        substring=$(echo $substring | sed s/%$1/\\\\\($(coresubstitute $1)\\\\\)/g)
        for i in e p s t h m; do
            substring=$(echo $substring | sed s/%$i/$(coresubstitute $i)/g)
        done
        echo $substring
    else
        echo unknown
    fi
}

parse()
{
    #Core pattern is of format %e_%p.by.%s.%t.%h.core
    #File name is of format process name_pid.by.signal.time.host.core.txt
    comp_file=$1

    # Strip down to base name
    comp_file=${comp_file##*/}

    # Parse out process name and pid number from file name
    core=${comp_file%.txt}

    context=$2
    if [ $context -eq $ALL_CONTEXTS ]; then
        context=1
    fi
    if [ -d $dir/.$context/ ]; then
        if [ -f $dir/.$context/$comp_file ]; then
            return
        else
            rm -f $dir/.$context/*
        fi
    else
        mkdir $dir/.$context
    fi

    if [ -f $dir/${comp_file} ]; then
        ln -sf $dir/${comp_file} $dir/.$context/${comp_file}
    else
        app=`echo ${core} | sed s/^$(getcorearg e)$/\\\\1/`
        pid=`echo ${core} | sed s/^$(getcorearg p)$/\\\\1/`
        sig=`echo ${core} | sed s/^$(getcorearg s)$/\\\\1/`
        loc=`echo ${core} | sed s/^$(getcorearg h)$/\\\\1/`

        {
            echo -e "Core for pid = $pid ($app)"
            echo -e "Core for process at $(pwd)/$1"
            echo -e "Core dump time: $(stat -c %z $comp_file)"
            echo -e

            echo -e "Process: $app "
            echo -e "Core was generated by:" $app@$loc
            echo -e

            echo -e "Signal information:"
            echo -e "Program terminated with signal: " $sig
            echo -e
        } > $dir/.$context/${comp_file}
    fi
}

MAX_CONTEXTS=10
CLEAR_CONTEXT=0
ALL_CONTEXTS=11

context_num=$(printf "%d\n" $2)

HOME=$(pwd)
cd $1 || exit 1
dir=$(pwd)

count=$MAX_CONTEXTS
if [ $context_num -eq $CLEAR_CONTEXT ]; then
    # delete *.txt file, so earlier corefiles aren't displayed in show context
    while [ $count -gt 0 ]; do
        if [ -d $dir/.$count ]; then
            rm -f $dir/.$count/* 2> /dev/null
        fi
        count=$[count-1]
    done
    find $dir -maxdepth 1 -name \*.core.txt -delete
    exit
fi

# xargs -n 500 chosen somewhat randomly. show context will produce erroneous results if
# number of .txt files in /misc/scratch/core exceeds that number.
file=($(find . -maxdepth 1 -name "*.core.txt" -type f | xargs -r -n 500 ls -t | cut -c3-))

#Number of files found
num_files=${#file[@]}

## Handle show context #
if [ $context_num -le $MAX_CONTEXTS ]; then
    if [ $context_num -le $num_files ]; then
        parse ${file[$context_num-1]} $context_num
    fi
elif [ $context_num -eq $ALL_CONTEXTS ]; then 
    # Handle show context (show all upto 10 recent)
    # This loop handles 'show context all', which is not
    # actually supported on XR (but is on calvados).
    for i in 0 1 2 3 4 5 6 7 8 9; do
        if [ -n "${file[$i]}" ]; then
            # CSCut69937:
            # We want the directories labeled starting from 1 rather than 0,
            # as all the rest of the code assumes starting from 1. Hence the
            # i + 1 argument
            parse ${file[$i]} $((i + 1))
        fi
    done
fi

cd $HOME
