#!/bin/sh
###
### Capture a sipXpbx configuration for reporting purposes
###

# Add /sbin to the end of PATH, because often if the user is not
# running as root or if he su'ed to root, /sbin will not be in the
# PATH, and ifconfig can't be found.  But put /sbin at the end of PATH
# in case the user prefers a different ifconfig that is already in the
# PATH.
PATH=$PATH:/sbin

Debug=NODEBUG
Action=SNAPSHOT
DoWebFiles=YES
SaveSecrets=NO
CoreFiles=
ExtraFiles=
CommentFiles=
Tar=YES
ToFile=
Logs=current
PercentageOfFile=
IncludeCallRecords="FALSE"
IncludeProfiles="FALSE"
GenerateCoreFiles=NO
DumpMongo=YES
Arguments=
InvokedAs="$0"

DefaultTarFile="sipx-configuration-`hostname -f`.tar.gz"

PROFILES_PATH="/var/sipxdata/configserver/phone/profile/tftproot"
PROFILES_SUBDIRS="Nortel/config"
ProfileExtensions="cfg xml csv ini"

# Define functions.

# Make a file name absolute.
# First argument is the file name, second is the default directory.
# If file name contains no /, prepend the default directory.
# If file name is relative, prepend the working directory.
# If file name is absolute, leave it unchanged.
# Output absolute file name to stdout.
function make_absolute () {
  case ${1} in
      /*)
          echo ${1}
          ;;
      */*)
          echo ${PWD}/${1}
          ;;
      *)
          echo ${2}/${1}
          ;;
  esac
}

# Process arguments.

Arguments="$*"
while [ $# -ne 0 ]
do
    case ${1} in

        --debug)
            Debug=DEBUG
            ;;

        -v|--version)
            echo 4.6.0
            exit;
            ;;

        -w|--www)
            DoWebFiles=YES
            ;;

        -nw|--no-www)
            DoWebFiles=NO
            ;;

        -l|--logs)
            if [ -z "${2}" ]
            then
                echo "No argument supplied for ${1}" 1>&2
                Action=USAGE
                break
            else
                Logs=`echo ${2} | tr A-Z a-z`
                case ${Logs} in
                    current|none|all)
                        :
                        ;;
                    [1-9]*)
                        if ! expr ${Logs} : '[1-9][0-9]*$' >/dev/null
                        then
                            echo "invalid selector for ${1}: '${2}'" 1>&2
                            Action=USAGE
                        fi
                        ;;
                    *)
                        echo "invalid selector for ${1}: '${2}'" 1>&2
                        Action=USAGE
                        ;;
                esac
            fi
            shift
            ;;

        -nl|--no-logs)
            Logs=none
            ;;

	-ll|--lines)
            if [ -z "${2}" ]
            then
                echo "No argument supplied for '${1}'" 1>&2
                Action=USAGE
                break
            elif `echo $2 | grep -q [^[:digit:]]`;
	    then
                echo "The argument supplied for '${1}' must be a number" 1>&2
                Action=USAGE
                break
            elif test "${Logs}" != "current"
            then
                echo "'${1}' may only be used with '--logs current'" 1>&2
                Action=USAGE
            elif [ "${2}" -gt 99 -o "${2}" -lt 1 ]
            then
                echo "'${1}' Must be between 1 and 99 inclusive" 1>&2
                Action=USAGE
            else           
                PercentageOfFile=${2}
                Logs=tail
	    fi
            shift
            ;;

        -c|--credentials|--include-secrets)
            SaveSecrets=YES
            ;;

        -i|--info-only)
            Action=INFO
            Tar=NO
            ;;

        -n|--notar)
            Tar=NO
            ;;

        --core)
            if [ -z "${2}" ]
            then
                echo "No argument supplied for --core" 1>&2
                Action=USAGE
                break
            fi
            CoreFiles="${CoreFiles} ${2}"
            shift
            ;;

        --profiles)
            IncludeProfiles="TRUE"
            ;;

        --cdr)
            IncludeCallRecords="TRUE"
            ;;

        --file)
            if [ -z "${2}" ]
            then
                echo "No argument supplied for --file" 1>&2
                Action=USAGE
                break
            fi
            ExtraFiles="${ExtraFiles} ${2}"
            shift
                 ;;

        --comment)
            if [ -z "${2}" ]
            then
                echo "No argument supplied for --comment" 1>&2
                Action=USAGE
                break
            fi
            CommentFiles="${CommentFiles} ${2}"
            shift
            ;;

        --generate-core-files)
            GenerateCoreFiles=YES
            ;;

        --nomongo)
            DumpMongo=NO
            ;;

        ##
        ## handle the 'end of options' marker
        ##
        --)
            ;;

        ##
        ## handle an unknown switch
        ##
        -*)
            echo "Unknown switch: ${1}" 1>&2
            Action=USAGE
            break
            ;;

        *)
            if [ -z "${ToFile}" ]
            then
                ToFile=${1}
            else
                echo "Too many arguments supplied: $@" 1>&2
                Action=USAGE
                break
            fi
            ;;
    esac

    shift # always consume 1 argument
done

if [ ${Tar} = YES ]
then
  # Set default ToFile if necessary.
  ToFile=${ToFile:-${DefaultTarFile}}
else
  # If Tar = NO, we copy the files directly to their destination.
  Work=${ToFile:-${Work}}
fi

if [ ${Action} = USAGE ]
then
  cat <<USAGE

Usage:

    sipx-snapshot [ --include-secrets | -c  | --credentials ]
                  [ -nw | --no-www ]
                  [ --profiles ]
                  [ --cdr ]
                  [ -l  | --logs {current|all|nnn|none} ]
                  [ -ll | --lines <number ranging from 1 to 99> ]
                  [ --core <core-file> ] ...
                  [ --file <file-name> ] ...
                  [ --comment <file-name> ] ...
                                       [ <tar-file-name> ]

    sipx-snapshot [ -i  | --info-only ]

    sipx-snapshot -n  | --notar
                  { options as in the first form }
                                       [ <to-directory-name> ]

    Collects important sipXpbx configuration information
    and saves it in a file.  This is used to record configuration
    information to accompany a problem report.

    In the default mode (the first form shown), the output file is a
    gzipped tar file named <tar-file-name>.  The default name is
    '${DefaultTarFile}'.  The tar file contains a text file named
    SystemConfig that describes various system configuration information,
    and the sipXpbx configuration files.

    The second form, with the --info-only switch, only the system
    configuration information is collected; none of the sipXpbx configuration
    files are included, and the output is to standard output.

    The third form, with the --notar switch, prevents the saved files from
    being tar'ed -- they remain in a file tree that mirrors the originals;
    in this case the final argument is the name of the directory where the
    information should be saved.

    By default, all passwords and other secrets are removed from the recorded
    configuration files.  If diagnosing a particular problem requires that the
    real secret information be included, the --include-secrets switch
    causes it to be left in.

    The --no-www switch disables saving the apache configuration files.

    The --logs switch selects which logs are saved:
               current - saves all the current logs (not those saved by logrotate)
               all     - saves all logs in the sipx log directory (large!)
               nnn     - saves all logs from the specified set of past logs
               none    - does not include any logs (not recommended)

    The --lines allow you to limit the log files size. Only the specified percentage
    of lines will be included in snapshot from tail logs. It may only be used with
    the 'current' logs (not with archived logs) and must be between 1 and 99 if
    specified.

    The --no-logs switch causes the sipX and Apache logs to be omitted
    from the snapshot; the default is to include them.  (deprecated but
    left in for backward compatibility - use '--logs none').

    The --profiles switch includes generated Phone and Gateway profile files,
    based on those that match a predefined filter.  Any passwords or other
    confidential information in these files will be included in the snapshot.

    The --cdr switch includes the data from call detail records; this is
    useful for debugging problems with the CDR system itself.

    The --core switch is used to specify the name of a core file to
    include among the files archived.  If the file name does not contain
    a /, it is searched for in /var/log/sipxpbx, otherwise it is searched for
    as usual.  The program 'file' is used to determine the corresponding
    executable file, the dynamic loader is used to determine the
    required dynamic libraries, and the executable and libraries are
    included among the files to be archived.  --core may be used
    multiple times.

    The --file switch is used to specify the name of a file to include
    among the files archived.  --file may be used multiple times.
    The argument to --file can be a wildcard, if it is quoted.

    The --comment switch is used to specify the name of a file to include
    among the files archived, but it will be at the top level of the saved
    file structure, rather than placed according to its full file name.
    --comment may be used multiple times.
    The argument to --comment can be a wildcard, if it is quoted.

    The --delete-logs option has been removed.

    During execution, sipx-snapshot constructs a temporary directory containing
    all the information to be saved, and sometimes additional temporary files.
    Especially if logs are included, this can occupy a lot of disk space.
    All temporary output is into the directory specified by \$TMPDIR (defaulting
    to /tmp), per the standard conventions.  If the execution of sipx-snapshot
    fails or is interrupted, it removes the temporary directory and files.

    If the --notar option is given, failure of sipx-snapshot does not
    cause the temporary files to be deleted.  Thus, when diagnosing a
    problem with sipx-snapshot's processing, use --notar.

    During execution, error output (stderr) while assembling the data
    is put in the file ./stderr in the temporary directory.  This file
    is saved in the resulting tar file, and at the end of execution,
    output to the pre-existing stderr.
USAGE
    exit
fi

# Establish the work directory, which will mirror the parts of the
# file system that we are interested in, with $Work corresponding to /.
# Since the destination location may not be able to hold the uncompressed
# data, place it in a recognized temporary location.
# (mktemp generates a unique name in $TMPDIR, or if that is not set, /tmp.)
Work=`mktemp -d -t sipx-snapshot.XXXXXX`
if [ ${Debug} = DEBUG ]
then
    echo "Work directory is ${Work}"
fi

# On exit, delete the work directory and any files whose names have
# the same prefix.
trap "rm -rf $Work* 2>/dev/null" 0

# Assemble the configuration information.
# Wrap the code that marshals the data in a shell function, which we call
# just once, immediately after its definition.
# After the function call, we create the tar file.

# Large information sets are put into separate files in the work directory.
# Miscellaneous information is output to stdout in this function, which
# is redirected to ./SystemConfig in the work directory in the function call.
# Capture any error output while assembling the snapshot data;
# the function call redirects stderr into "tee ${Work}/stderr >&2".

# Using a shell function is better than wrapping the commands in a pipe,
# because the shell reports all errors in a pipe using the line number
# of the start of the pipe.  It also gives us better control over redirection.

# File into which to record random system configuration information.
SystemConfig=${Work}/SystemConfig

function marshal_configuration_information () {
   # Files into which the postgres databases are dumped
   ConfigDb=${Work}/SIPXCONFIG
   CallStateDb=${Work}/SIPXCSE
   CallDetailDb=${Work}/SIPXCDR

   function tailLogs() {
     mkdir -p ${cutDir}/${2}
     MinSize=102400
     FsSize=`du -b ${1} | awk '{ print $1 }'`
     TailSize=$[ ( $FsSize * $PercentageOfFile ) / 100 ]
     DestFile=${cutDir}/$2`basename "${1}"`

     # files under a 100K, take whole file, this is really about
     # avoiding humongous snapshots.
     if [ $FsSize -lt $MinSize ]; then
       cp ${1} $DestFile
     else
       if [ $TailSize -lt $MinSize ]; then
  	 TailSize=$MinSize
       fi
       tail -c $TailSize "${1}" > $DestFile
     fi
     echo $DestFile >> $Work.copy-files
   }

   # Assemble the list of files to record.
   # These files and directories are always recorded.
   cat > $Work.copy-files <<EOF
   /etc/sipxpbx
   /var/sipxdata/sipdb
   /etc/host.conf
   /etc/resolv.conf
   /etc/named.conf
   /etc/ntp.conf
   /etc/ntp
   /etc/hosts
   /etc/crontab
   /etc/sendmail.cf
   /var/run/sipxpbx
   /var/sipxdata/cfdata
   /usr/share/sipxecs/cfinputs
   /opt/openfire/logs/debug.log
   /opt/openfire/logs/info.log
   /opt/openfire/logs/error.log
   /opt/openfire/logs/warn.log
   /opt/openfire/logs/sipxopenfire.log
   /var/named
   /var/log/yum.log
   /var/log/messages
   /var/log/mongodb
   /etc/yum.conf
   /etc/yum
   /etc/yum.repos.d
EOF

  #recurse into directories;
  function tailLogs() {
    mkdir -p ${cutDir}/${2}
    filename=`basename "${1}"`
    foldername=${2}
    if [ -d ${1} ]; then
      for log in ${1}/*
      do
	foldername=`basename ${1}`${2}
	tailLogs $log ${2}/`basename ${1}`/
      done
    else

     MinSize=102400
     FsSize=`du -b ${1} | awk '{ print $1 }'`
     TailSize=$[ ( $FsSize * $PercentageOfFile ) / 100 ]
     DestFile=${cutDir}/$2`basename "${1}"`

     # files under a 100K, take whole file, this is really about
     # avoiding humongous snapshots.
     if [ $FsSize -lt $MinSize ]; then
       cp ${1} $DestFile
     else
       if [ $TailSize -lt $MinSize ]; then
  	 TailSize=$MinSize
       fi
       tail -c $TailSize "${1}" > $DestFile
     fi
     echo ${DestFile} >> $Work.copy-files
    fi
  }

   # Add the requested log files
   case ${Logs} in
       none)
	   :
	   ;;
       tail)
	   # The extract files we create in ${cutDir} will be copied into
	   # the working tree.  In later processing, the files will be moved into
	   # ${Work}//var/log/sipxpbx itslef, and ${Work}/${cutDir} will be deleted.
	   cutDir=`mktemp -d /var/log/sipxpbx/cut.XXXXXX`
	   trap "rm -rf ${cutDir} 2>/dev/null" 0

	   for base_log in `find /var/log/sipxpbx -maxdepth 1 -name '*log'`
	   do
	     tailLogs $base_log
  	   done

	   ! test -d /var/log/sipxpbx/phone || for base_log in `find /var/log/sipxpbx/phone -maxdepth 1 -name '*.log'`
	   do
	     tailLogs $base_log phone/
	   done

	   ! test -d /var/log/sipxpbx/trace || for base_log in `find /var/log/sipxpbx/trace -maxdepth 1 -name '*.pcap*'`
	   do
	     tailLogs $base_log trace/
	   done
	   ;;
       current)
	   for log in /var/log/sipxpbx/*log /var/log/sipxpbx/phone/*.log /var/log/sipxpbx/trace/*.pcap*
	   do
	     echo $log >> $Work.copy-files
	   done
	   ;;
       [1-9]*)
	   if ! ls -1 \
		/var/log/sipxpbx/*log.${Logs}{,.gz} \
		/var/log/sipxpbx/phone/*.log.${Logs}{,.gz} \
		2>/dev/null \
		| grep '.' \
		>> $Work.copy-files
	   then
	       echo "Can't find any log files for past day ${Logs}:" >&2
	       echo "    /var/log/sipxpbx/*log.${Logs}{,.gz}: No such file or directory" >&2
	   fi
	   ;;
       all)
	   for log in /var/log/sipxpbx/*log  /var/log/sipxpbx/*log.* /var/log/sipxpbx/phone/*.log.* /var/log/sipxpbx/trace/*.pcap*
	   do
	     echo $log >> $Work.copy-files
	   done
	   ;;
   esac

   # Add the --file files to the list.
   for File in ${ExtraFiles}
   do
     # Point the file name to $PWD if it has no /.
     File=`make_absolute ${File} ${PWD}`

     # Check that the file exists.
     if [ ! -e ${File} ]
     then
	 echo File ${File} does not exist. 1>&2
	 exit 1
     fi

     # Add the file name to the list.
     echo "${File}" >> $Work.copy-files
   done

   # Copy the --comment files to $Work.
   CommentFileSeqNo=1
   for File in ${CommentFiles}
   do
     # Point the file name to $PWD if it has no /.
     File=`make_absolute ${File} ${PWD}`

     # Check that the file exists.
     if [ ! -e ${File} ]
     then
	 echo File ${File} does not exist. 1>&2
	 exit 1
     fi

     # Copy the file into the work directory, giving it a name that is unique.
     cp -pR --dereference ${File} ${Work}/Comment:`basename ${File}`:${CommentFileSeqNo}
     (( CommentFileSeqNo++ ))
   done

   # Record miscellaneous information about the host.

   echo -n "Snapshot:  "
   echo "${InvokedAs}"
   echo -n "Arguments: "
   echo "$Arguments    "
   echo ""
   echo -n "Version:   "
   echo "4.6.0"
   echo ""
   echo -n "Host:      "
   hostname --fqdn
   echo ""
   echo -n "Date:      "
   date -u
   echo -n "           "
   date
   echo ""
   if [ -n "${PercentageOfFile}" ]
   then
     echo "Tail ${PercentageOfFile} percent of log file"
     echo ""
   fi
   echo -n "SysVersion: "
   uname -a
   if [ -f /etc/issue ]
   then
     echo ""
     echo "Release (/etc/issue):"
     cat /etc/issue
   fi
   if [ -f /etc/redhat-release ]
   then
     echo ""
     echo "Release (/etc/redhat-release):"
     cat /etc/redhat-release
   fi
   echo ""
   echo    "sipXpbx User:"
   grep sipx /etc/passwd
   echo ""
   echo "SELinux:"
   if selinuxenabled               2>&1
   then
       echo -n "   Enabled; mode="
       getenforce
   else
       echo    "   Disabled"
   fi
   echo ""

   echo "NTP Peers:"
   /usr/sbin/ntpq -p               2>&1
   echo ""

   echo "SSL Configuration:"
   ls -lR /etc/sipxpbx/ssl/
   echo "  Certificate Dump:"
   cat /etc/sipxpbx/ssl/ssl.crt  2>&1
   echo ""

   # Set the file name to hold the output from core file and backtrace manipulation.
   Backtrace=${Work}/Backtrace

   # If requested, create core files for all the processes.
   # If not, get backtraces of all processes.
   if [ ${GenerateCoreFiles} = YES ]
   then
       echo ======== Generate core files for all sipX processes > ${Backtrace}
       for PID_FILE in /var/run/sipxpbx/*.pid
       do
	   PID=`cat ${PID_FILE}`
	   # Generate the core file into the same directory as we created the
	   # work directory, so a single 'rm' can delete them all.
	   FILE=${Work}.core.${PID}
	   echo
	   echo Generate core file for ${PID_FILE%.pid} process number $PID into ${FILE}
	   echo
	   if [[ -n "${PID}" ]]
	   then
	       time \
		   gdb < /dev/null \
		   -eval-command "attach ${PID}" \
		   -eval-command 'thread apply all backtrace' \
		   -eval-command "generate-core-file ${FILE}" \
		   -eval-command detach \
		   -eval-command quit
	       # Check that we managed to create the core file.
	       if test -e ${FILE}
	       then
		   CoreFiles="${CoreFiles} ${FILE}"
	       else
		   echo Could not generate core file ${FILE} for process number $PID
	       fi
	   fi
       done
   else
       echo ======== Backtrace of all sipX processes > ${Backtrace}
       for PID_FILE in /var/run/sipxpbx/*.pid
       do
	   PID=`cat ${PID_FILE}`
           # Check that PID file is non-empty.
           # (Openfire seems to empty the PID file rather than deleting it.)
           if [[ -n "$PID" ]]
           then
	       echo
	       echo Process ${PID_FILE%.pid} number ${PID}
	       echo
	       if [[ -n "${PID}" ]]
	       then
		   time \
		       gdb < /dev/null \
		       -eval-command "attach ${PID}" \
		       -eval-command 'thread apply all backtrace' \
		       -eval-command detach \
		       -eval-command quit
	       fi
	       echo
           fi
       done
   fi >> ${Backtrace} 2>&1

   # Process the core file specifications (if any) into the list of files to save
   # and include details in SystemConfig.

   Cores_Backtrace=${Work}/Cores_Backtrace
   # If core files were specified, determine the files to be copied.
   cat /dev/null >${Work}.core-related-files
   if [ -n "${CoreFiles}" ]
   then
     # Add /usr/lib/debug, which contains the separated symbol tables.
     echo /usr/lib/debug >>${Work}.core-related-files
   fi
   for Core in ${CoreFiles}
   do
     # Point the core file name to SIPX_LOGDIR if it has no /.
     Core=`make_absolute ${Core} /var/log/sipxpbx`

     # Check that the file exists.
     if [ ! -e ${Core} ]
     then
	 echo File ${Core} does not exist. 1>&2
	 exit 1
     fi

     # Run 'file' on it.
     file_output="`file ${Core}`"

     # Verify that it is a core file.
     if [[ "${file_output}" != *" core file "* ]]
     then
	 echo File ${Core} is not a core file. 1>&2
	 echo "'file ${Core}' reports: $f" 1>&2
	 exit 1
     fi

     # Look for the executable in the known binary directories.
     ReportedExec='(none)'
     AbsoluteExec='(unknown)'
     # Calculate the directory containing the Java executable.
     # In some Java systems, the official Java executable is a symbolic link to
     # a script that exec's the Java binary executable, and the Java binary
     # executable is in the same directory as that script.
     # So to find the executable for a Java core file, we may have to look in the
     # real directory containing the official Java executable, rather than
     # the directory containing its official name (which may be a symbolic link).
     JAVA_BIN=`sipx-config --java`
     JAVA_REAL=`readlink -f $JAVA_BIN`
     JAVA_BINDIR=${JAVA_REAL%/*}
     BindirList=" \
	     /usr/bin \
	     /usr/lib/sipXecs \
	     @FREESWITCH_PREFIX@/bin \
	     /opt/openfire/bin \
	     /usr/bin \
	     /usr/sbin \
	     ${JAVA_BINDIR}"
     if [[ "${file_output}" = *" from "* ]]
     then
	 ReportedExec="${file_output##*\ from\ \'}"
	 ReportedExec="${ReportedExec%\'}"

	 # (If ${ReportedExec} is already absolute, every iteration of this loop
	 # will do the same thing.)
	 for Bindir in ${BindirList}
	 do
	     F=`make_absolute ${ReportedExec} ${Bindir}`
	     if [ -x "${F}" ]
	     then
		 AbsoluteExec="${F}"
		 break
	     fi
	 done
     fi

     echo ""
     echo "Core file: ${Core}"
     echo "${file_output}"
     echo "from executable: ${AbsoluteExec}"

     # Get a backtrace of the core file.
     # (The user could do this based on the files we are saving, but
     # it's easier if this script does it.)
     (
	 echo ======== Backtrace of ${Core}
	 echo
	 gdb -core=${Core} < /dev/null \
	     -eval-command 'thread apply all backtrace' \
	     -eval-command quit
	 echo
      ) >> ${Cores_Backtrace} 2>&1

     # Accumulate the list of files to be added to the snapshot.
     echo "${Core}" >>${Work}.core-related-files

     # Check that the executable file exists.
     if [ "${ReportedExec}" = '(none)' -o "${ReportedExec}" = '' ]
     then
	 : Do nothing
     elif [ "${AbsoluteExec}" = '(unknown)' ]
     then
	 echo "File '${ReportedExec}', the reported executable for ${Core}, " \
	      "cannot be found in:" ${BindirList} \
	      1>&2
	 echo "Warning: '${ReportedExec}' cannot be found in:" ${BindirList}
     else
	 echo "${AbsoluteExec}" >>${Work}.core-related-files

	 # Get the dynamic libraries this executable needs.
	 ldd ${AbsoluteExec} |
	 perl -pe 's|^.*=>\s*||; s|\s*\(.*$||; s|^\s*||' \
	     >>${Work}.core-related-files
     fi

   done

   # Remove duplicates from the list, and add it to $Work.copy-files
   sort -u ${Work}.core-related-files >>$Work.copy-files

   # Get DNS and hostname information
   locale=""
   full_host=`hostname --fqdn | tr A-Z a-z`
   full_locale=$full_locale

   while [ -n "$full_locale" ]
   do
       locale="$full_locale $locale"
       full_locale=`echo $full_locale | sed 's/^[^.]*\.//; s/^[^.]*$//'`
   done

   . /usr/lib/sipXecs/sipx-utils.sh || exit 1
   echo ""

   echo ""
   echo "======== START DNS LOOKUPS"

   sipDomain=`sipx_config_value /etc/sipxpbx/domain-config SIP_DOMAIN_NAME`
   echo "SIP_DOMAIN_NAME = '${sipDomain}'"

   echo ""
   echo "==== NS $sipDomain = `dns_ns $sipDomain`"

   echo "==== NAPTR $sipDomain"
   dig -t naptr +noidentify +nocmd +nocomments +noquestion +nostats +noauthority $sipDomain \


   echo "==== SRV $sipDomain"
   dig -t srv +noidentify +nocmd +nocomments +noquestion +nostats +noauthority _sip._tcp.$d _sip._udp.$d \
   | sort -u -r \


   tcpProxies=`dns_sipsrv tcp $sipDomain`
   echo "TCP Proxies: ${tcpProxies}"
   udpProxies=`dns_sipsrv udp $sipDomain`
   echo "UDP Proxies: ${udpProxies}"

   Proxies=`for p in ${udpProxies} ${tcpProxies} ; do echo $p; done | sort -u`

   test -z "${Proxies}" && echo "! No Proxies in DNS for '$sipDomain'"

   for p in ${Proxies}
   do
     echo ""
     echo "==== Registrar SRV for $p"
     dig -t srv +noidentify +nocmd +nocomments +noquestion +nostats +noauthority _sip._tcp.rr.$p _sip._udp.rr.$p \

   done

   for p in $sipDomain ${Proxies}
   do
       echo ""
       for t in CNAME A
       do
	   echo "==== $t for $p"
	   dig -t $t +noidentify +nocmd +nocomments +noquestion +nostats +noauthority $p \
	
       done
   done

   echo ""
   echo "==== MWI SRV for $sipDomain"
   dig -t srv +noidentify +nocmd +nocomments +noquestion +nostats +noauthority _sip._tcp.mwi.$d \

   echo ""
   echo "==== VM SRV for $sipDomain"
   dig -t srv +noidentify +nocmd +nocomments +noquestion +nostats +noauthority _sip._udp.vm.$d \

   echo ======== END DNS LOOKUPS

   # Get version info for key prerequisite packages
   for prereq in pcre glib
   do
     echo ""
     prereq_version=`${prereq}-config --version 2> /dev/null`
     if test $? -eq 0
     then
	 echo -n "$prereq --version : ${prereq_version}"
     else
	 echo -n "$prereq --version : (not available)"
     fi
   done

   # Get info on installed sipx rpms
   for sipName in `rpm -qa --nodigest --nosignature | grep sipx`
   do
      echo ""
      echo "======== RPM $sipName"
      rpm -qi $sipName
   done

   echo "======== RPMs"
   rpm -qa --nodigest --nosignature | sort

   echo ""
   echo "======== INTERFACES (ifconfig -a)"
   ifconfig -a

   echo ""
   echo "======== ROUTES (route -n)"
   route -n

   # Get any firewall or other tricky IP manipulations
   echo ""
   echo "======== IPTables:"
   for t in nat filter mangle
   do
     echo "=== $t table:"
     iptables --table $t --list --verbose --numeric --line-numbers 2>&1
   done

   # Execute system monitoring commands
   for command in \
       "ps -efww" \
       "netstat -ap --ip --numeric-hosts" \
       "top n 1 b" \
       "vmstat 5 2" \
       "free" \
       "df -h" \
       "ls -ld /tmp"
   do
     echo ""
     echo ======== $command
     $command 2>&1
   done

   # Get a good directory listing of the system
   # Variable assignments for the command cannot be put in a variable that is
   # substituted into the command line.
   command='ls -lR /usr/bin /etc/sipxpbx /usr/share/sipxecs /var/sipxdata/sipdb /usr/lib /usr/lib/sipXecs /var/log/sipxpbx /var/run/sipxpbx /var/sipxdata /usr/bin /usr/share/www'
   DirListing=${Work}/ls-lR
   echo ======== TZ=UTC $command  > ${DirListing}
   echo                          >> ${DirListing}
   TZ=UTC $command               >> ${DirListing}

   # Collect sipX configuration information
   echo ""

   if [ "${Action}" = "SNAPSHOT" ]
   then
     # Record the sipXconfig database contents
     pg_dump -U postgres --attribute-inserts SIPXCONFIG > ${ConfigDb}

     if [ "${IncludeCallRecords}" = "TRUE" ]
     then
	 # Record the call state event and detail record database contents
	 pg_dump -d SIPXCDR -U postgres --attribute-inserts > ${CallDetailDb} 2> /dev/null
     fi

     # Include the Phone and Gateway profile files, if specified.
     if [ "${IncludeProfiles}" = "TRUE" ]
     then
       # First gather all files that match simply a MAC address with no extension, and add
       # back the path.  (The main LG-Nortel 68xx Profile file has this format.)
       ProfileFiles=""
       for macfile in `ls ${PROFILES_PATH} | grep -E "^[0-9a-fA-F]{12}$" 2> /dev/null`
       do
	   echo "${PROFILES_PATH}/${macfile}" >> $Work.copy-files
       done

       # Loop through all the profile file extensions to be picked up.
       for Extension in ${ProfileExtensions}
       do
	   for configfile in `ls ${PROFILES_PATH}/*.${Extension} 2> /dev/null`
	   do
	       echo "${configfile}" >> $Work.copy-files
	   done
       done
       for subdir in ${PROFILES_SUBDIRS}
       do
	   if [ -d ${PROFILES_PATH}/${subdir} ]
	   then
	       for Extension in ${ProfileExtensions}
	       do
		   for configfile in `ls ${PROFILES_PATH}/${subdir}/*.${Extension} 2> /dev/null`
		   do
		       echo "${configfile}" >> $Work.copy-files
		   done
	       done
	   fi
       done
     fi

     # Copy all the files and directories that should be copied.
     for file in `sort -u $Work.copy-files`
     do
       echo "======== copying ${file}"
       copyFile=`basename ${file}`
       copyDir=${Work}`dirname ${file}`
       test -d ${copyDir} || mkdir -p ${copyDir}
       if [ -f ${file} ]
       then
	 # This is 'cp --archive', except with '--dereference'.
	 # '--dereference' is necessary, because if we're saving dynamic libraries
	 # for a core file, the linked dynamic library names are almost always
	 # symlinks.
	 cp -pR --dereference ${file} ${copyDir}/${copyFile} 2>&1
       elif [ -d ${file} ]
       then
	 cp -pR --dereference ${file} ${Work}${file} 2>&1
       else
	 echo Missing or not a file/directory: ${file}
	 # Show what the object is, if it exists.
	 ls -ld ${file} 2>/dev/null
       fi
     done

     # Remove the secret values from configuration unless told not to.
     if [ ${SaveSecrets} = NO ]
     then
       for file in `find $Work -name domain-config`
       do
	 perl -pi \
	       -e 's|SHARED_SECRET +: +.*|SHARED_SECRET : ELIDED|' \
	      ${file}
       done
       for file in `find $Work -name sipxbridge.xml`
       do
	 perl -pi \
	       -e 's|<user-name>[^<]*</user-name>|<user-name>ELIDED</user-name>|;' \
	       -e 's|<password>[^<]*</password>|<password>ELIDED</password>|' \
	      ${file}
       done
       perl -pi /usr/lib/sipXecs/sipx-strip-db-secrets.pl ${ConfigDb}
     fi

     # If we tail the logs,
     #   relocate them as though they were full logs in the working copy to be tarred
     #   delete the cut copy under the original log directory
     if [ "${Logs}" = "tail" ]
     then
	 mv ${Work}${cutDir}/* ${Work}/var/log/sipxpbx
	 rmdir ${Work}${cutDir}
	 rm -rf ${cutDir}
     fi

   fi

   #Dump the mongo database in bson format
   #This script assumes mongo is running
   if [ ${DumpMongo} = YES ]
   then
     if [ ${SaveSecrets} = NO ]
     then
       mongoexport -d imdb -c entity | sed -e 's/"pstk" : ".*", "pntk" : ".\{32\}"/"pstk" : "ELIDED", "pntk" : "ELIDED"/g' -e 's/"pstk" : ".\{10\}",/"pstk" : "ELIDED",/g' > ${Work}/mongo.imdb.entity.json
     else mongoexport -d imdb -c entity -o ${Work}/mongo.imdb.entity.json
     fi
     mongoexport -d imdb -c node -o ${Work}/mongo.imdb.node.json
     mongoexport -d node -c registrar -o ${Work}/mongo.node.registrar.json
     mongoexport -d node -c subscription -o ${Work}/mongo.node.subscription.json
   fi
}

# Now execute the code in the function that we have just defined.
# stdout will be written in ./SystemConfig, while stderr will be written
# into both ./SystemConfig and ./stderr.
( marshal_configuration_information 2>&1 1>&3 | tee ${Work}/stderr ) >${SystemConfig} 3>&1

# Output any stderr output to the user.
cat ${Work}/stderr

for i in `ls /usr/bin/snapshot/`;
  do /usr/bin/snapshot/$i ${Work};
done;

if [ ${Tar} = YES ]
then
  # Tar the entire directory tree and compress it.
  # (Writing this pipe explicitly allows us to use tar's that do not understand
  # the -z option.)
  tar cf - -C ${Work} . | gzip >${ToFile}
  # Remove the temporary files.
  rm -rf $Work
  chmod 644 ${ToFile}

  echo "Configuration saved in '${ToFile}'"

elif [ "${Action}" = "INFO" ]
then
  cat ${SystemConfig}
  echo "(Configuration information is in '${SystemConfig}')"

else
  # Remove the trap that would delete the work directory that we are about to
  # tell the user about.
  trap - 0
  echo "Configuration saved in '${Work}'"
fi

# Remove the temporary files.
rm -rf $Work.copy-files $Work.delete-files $Work.core-related-files
