#!/bin/sh
#
# ------------------------------------------------------------------
#  show_files.sh
#
#  October 2010, Michael C. Scott
#
#  Copyright (c) 2010-2012 by Cisco Systems, Inc.
#  All rights reserved.
# ------------------------------------------------------------------


# Prints a header before iterating over the specified nodes (printing a node
# header if it iterates over more than one node). Within each node it iterates
# over the processes on the node. Depending on the "-v" (verbose) flag one of
# two actions occur:
# 1. Without "-v" - For each process retrieve the process name, number of open
#    channels and number of open files then print the information.
# 2. With "-v" - For each process retrieve the process name and a list of open
#    files. The process name is printed along with the number of open files
#    before printing a list of open files.


# SH_PROC_FILES*_FORMAT_STRING
#
# The format string used when printing information.
SH_PROC_FILES_FORMAT_STRING="%-10.10s %-10.10s %-10.10s %-15.15s\n"
SH_PROC_FILES_DETAIL_FORMAT_STRING="%-18s %-20s\n"


# SH_PROC_FILES_LINE_OF_DASHES
#
# A string of dashes used to separate items.
SH_PROC_FILES_LINE_OF_DASHES=`printf "%61s" "" | tr ' ' '-'`


# Load the show_proc / pidin library.
source `dirname $0`/sh_proc_lib


function main
{
    local node_list=""
    local process_list=""

    if [ $sh_proc_verbose_flag -eq 0 ]; then
        printf "$SH_PROC_FILES_FORMAT_STRING" \
               "PID" "Open-Files" "Open-Channels" "NAME"
    fi

    # Generate a list of nodes.
    sh_proc_node_iterator
    node_list=("${sh_proc_node_iterator_out[@]}")

    # Iterate over each node.
    for node in ${node_list[@]}; do
        # If there are multiple nodes we print a header for each node.
        if [ ${#node_list[@]} -gt 1 ]; then
            sh_proc_print_node_header $node
        fi
        # Set the path for the /proc filesystem of the current node.
        sh_proc_set_proc_path $node

        # Genereate a list of processes.
        sh_proc_process_iterator $node
        process_list=($sh_proc_process_iterator_out)
        # Generate a list of PIDs from the process list.
        #sh_proc_pid_list_to_jid_list_in=("${process_list[@]}")
        #sh_proc_pid_list_to_jid_list
        #jid_list=($sh_proc_pid_list_to_jid_list_out)

        # Iterate over each process.
        local index=0
        while [ $index -lt ${#process_list[@]} ]; do
            local process=${process_list[$index]}

            sh_proc_get_item $process "basename15"
            name_out=$sh_proc_get_item_out
            #If appropriate get the number of open channels.
            if [ $sh_proc_verbose_flag -eq 0 ]; then
                sh_proc_get_item $process "open_channels"
                open_channels_out=$sh_proc_get_item_out
            fi
     
            #Get an array containing the file descriptors.
            sh_proc_get_file_descriptors $process
            file_descriptors=("${sh_proc_get_file_descriptors_out[@]}")

            # If the information was succesfully retrieved print it. If the
            # PID could not be converted to a PID print an apporpriate
            # error message.
        #    if [ $? -eq 0 -a $sh_proc_get_item_error -eq 0 ]; then
        #        if [ ${jid_list[$index]} == "-1" ]; then
        #            printf "Failed to get jobid from pid\n"
        #        else
                    if [ $sh_proc_verbose_flag -eq 0 ]; then
                        printf "$SH_PROC_FILES_FORMAT_STRING" \
                        $process ${#file_descriptors[@]} \
                               "Open-Channels" $name_out            
                    else
                        # If the verbose flag is active retrieve information
                        # for each file descriptor and print it.
                        printf "Pid: %-8d Total open files: %-8d Name: %-20s\n" \
                               $process ${#file_descriptors[@]} $name_out

                        printf "%s\n" "$SH_PROC_FILES_LINE_OF_DASHES"

                        printf "$SH_PROC_FILES_DETAIL_FORMAT_STRING" \
                               "File Descriptor" "Process Name"

                        printf "$SH_PROC_FILES_DETAIL_FORMAT_STRING" \
                               "---------------" "------------"

                        for file in ${file_descriptors[@]}; do
                            file_info=`readlink $sh_proc_node_proc_path/$process/fd/$file 2>/dev/null`
                            printf "$SH_PROC_FILES_DETAIL_FORMAT_STRING" \
                                   "$file" "$file_info"
                        done

                        printf "%s\n\n" "$SH_PROC_FILES_LINE_OF_DASHES"
                    fi
        #        fi
        #    else
        #        sh_proc_get_item_error=0
        #    fi
            let index+=1
        done       
        printf "\n"
    done
}


sh_proc_command_parser "$@"
main
