#!/bin/bash
#
# Univention System Info
#  collects information about the hardware
#
# SPDX-FileCopyrightText: 2009-2025 Univention GmbH
# SPDX-License-Identifier: AGPL-3.0-only

TEMPDIR=$(mktemp -d)
PROCFILES="cpuinfo devices dma filesystems interrupts meminfo partitions version scsi/scsi mounts"
PROGRAMS="lspci__-vnn lsmod dmidecode univention-config-registry__search__--brief__version/version__version/patchlevel__version/security-patchlevel"

manufacturer=
model=
comment=
ticket=
umc=

collect_from_procfile() {
	if [ -e "/proc/$1" ]
		then
		[ -z "$umc" ] && echo -n ": $1"
		filename=$(echo "$1" | sed -e 's|/|_|g')
		cat "/proc/$1" > "$TEMPDIR/proc/$filename"
	fi
}

collect_from_program() {
	cmd=$(echo "$1" | sed -e 's/__/ /g')
	tmpfile=$(echo "$1" | sed -e 's/__.*//')
	$cmd > "$TEMPDIR/$tmpfile"
	[ -z "$umc" ] && echo -n ": $cmd"
}

display_help() {
	display_header
	cat <<-EOL
	Syntax:
	  $0 [options]

	Options:
	  -m | --manufacturer:
	    set value for manufacturer of the system

	  -t | --typ:
	    set typ/model of the system

	  -c | --comment:
	    set a descriptive comment

	  -s | --support:
	    set a support ticket number

	  -u | --umc:
	    produces a better parsable output

	  -h | --help:
	    print this usage message and exit program

	  --version
	    print version information and exit program

	Description:
	  $0 collects some hardware-related information
	  about your system, e.g. CPU, memory and filesystems.

	EOL
	exit 0
}

display_header() {
	echo "univention-sysinfo: collect information about your system"
	echo "Copyright 2009-2025 Univention GmbH, Germany"
	echo ""
}

display_version() {
	echo "$0 0.1.4-1"
	exit 0
}

while getopts "hvm:t:c:f:s:u" OPTION; do
	case $OPTION in
		v|-version)
			display_version
			;;
		m|-manufacturer)
			manufacturer=$OPTARG
			;;
		t|-type)
			type=$OPTARG
			;;
		c|-comment)
			comment=$OPTARG
			;;
		s|-support)
			support=$OPTARG
			;;
		f|-file)
			file=$OPTARG
			;;
		u|-umc)
			umc=yes
			;;
		*)
			display_help
			;;
	esac
done

if [ -z "$manufacturer" -o -z "$type" ]; then
	echo "error: manufacturer and type/model of the system must be provided"
	display_help
	exit 1
fi

[ -z "$umc" ] && echo -n " Update PCI ID list: "
if update-pciids > /dev/null 2>&1; then
	[ -z "$umc" ] && echo "done"
else
	[ -z "$umc" ] && echo "warning: PCI ID list couldn't be updated"
fi

mkdir "$TEMPDIR/proc" > /dev/null 2>&1
if [ -n "$umc" ]; then
	echo "Temp: $TEMPDIR"
else
	echo " Collect system information:"
fi

[ -z "$umc" ] && echo -n " /proc ... "
for proc in $PROCFILES; do
  collect_from_procfile "$proc"
done
if [ -z "$umc" ]; then
	echo "done"

	echo -n " program ... "
fi
for prog in $PROGRAMS; do
  collect_from_program "$prog"
done
[ -z "$umc" ] && echo ""

echo " Manufacturer: "$manufacturer > "$TEMPDIR/info"
echo " Model       : "$type >> "$TEMPDIR/info"
echo " Comment     : "$comment >> "$TEMPDIR/info"
echo " Ticket No   : "$support >> "$TEMPDIR/info"

# find unique ID for the computer
uuid=$(dmidecode -s system-uuid | grep -v '^#' | tr -cd '[:alnum:][=-=]')
if [ -z "$uuid" ]; then
	# fallback 1
	if [ -f /sys/hypervisor/uuid -a $(cat /sys/hypervisor/uuid) != "00000000-0000-0000-0000-000000000000" -a $(cat /sys/hypervisor/type) != "xen" ]; then
		uuid=$(cat /sys/hypervisor/uuid | tr -cd '[:alnum:][=-=]')
	else
		# fallback 2
		uuid=$(ip -o -f link addr show up | grep -v lo: | head -n 1 | sed 's|.*link/ether \([0-9a-f:]*\) .*|\1|;s|:|-|g' | md5sum | cut -d ' ' -f1)
	fi
fi

cd /tmp

if [ -e "$uuid" ]; then mv "$uuid" "$uuid.bak.$(date +%s)"; fi
if [ -e "$file" ]; then mv "$file" "$file.bak.$(date +%s)"; fi
if [ -e "$uuid.tar.gz" ]; then mv "$uuid.tar.gz" "$uuid.tar.gz.bak.$(date +%s)"; fi

mv "$TEMPDIR" "$uuid"
if [ -n "$file" ]; then
	tar czf "$file" "$uuid" > /dev/null 2>&1
	archive=$file
else
	tar czf "$uuid.tar.gz" "$uuid" > /dev/null 2>&1
	archive=/tmp/$uuid.tar.gz
fi
rm -rf "$uuid"

if [ -z "$umc" ]; then
	echo ""
	echo "Collection of system-information finished."
	echo "Archive: $archive"
else
	mv "$archive" /usr/share/univention-system-info/archives/
	base_name="$(basename "$archive")"
	chmod 444 "/usr/share/univention-system-info/archives/$base_name"
	chown www-data:www-data "/usr/share/univention-system-info/archives/$base_name"

	echo "archive:$(basename "$archive")"
	echo "cpu:$(grep -m 1 "^model name" /proc/cpuinfo | sed 's/model name[ \t] *: //')"
	echo "num_cpu:$(grep -c "^processor" /proc/cpuinfo)"
	echo "mem:$(grep "^MemTotal:" /proc/meminfo | sed 's/MemTotal:[ \t]*//')"
	echo "net_dev:$(lspci | egrep " (Network|Ethernet) controller: " | sed 's/.* \(Network\|Ethernet\) controller: //')"
	echo "gfx_dev:$(lspci | grep " VGA compatible controller: " | sed 's/.* VGA compatible controller: //')"
fi
