cleanup output and help text
[grml-hwinfo.git] / grml-hwinfo
1 #!/bin/sh
2 # Filename:      grml-hwinfo
3 # Purpose:       get hardware information
4 # Authors:       grml-team (grml.org), (c) Michael Prokop <mika@grml.org>
5 # Bug-Reports:   see http://grml.org/bugs/
6 # License:       This file is licensed under the GPL v2.
7 ################################################################################
8 # Notice: Some ideas have been taken from
9 # http://club.black.co.at/david/hwdb/infodump
10 # by David Schmitt <david@schmitt.edv-bus.at>
11 ################################################################################
12
13 # variables
14 UNAME="$(uname -r)"
15 PN="$(basename $0)"
16 [ -n "$WORKING_DIR" -a -d "$WORKING_DIR" ] || WORKING_DIR=$(pwd)
17 VERSION='0.4.1'
18
19 TIMESTAMP='+%F--%H-%M-%S-%Z'
20 DATE="$(date $TIMESTAMP)"
21
22 echo "$PN ${VERSION} - collect hardware information"
23
24 GENERATE_FILE='1'
25 GENERATE_DIRECTORY=''
26
27 while getopts "hdf" args; do
28   case "$args" in
29   h) echo "
30 This tool collects information of the hardware this tool is being executed
31 on.  It can be executed as normal user to collect some basic information or
32 with root permissions to collect as much information as possible.  By
33 default, a file named grml-hwinfo-TIMESTAMP.tar.bz2 storing all collected
34 information will be created in the current working directory. Alternatively,
35 you can have it create a directory with all information.
36
37 Options:
38
39   -h    Display this help message
40   -f    Create grml-hwinfo-TIMESTAMP.tar.bz2
41   -d    Create grml-hwinfo-TIMESTAMP as a directory
42   -df   Create both, the directory and the file
43 "
44
45   exit 0;;
46
47   d)
48   GENERATE_FILE=''
49   GENERATE_DIRECTORY='1'
50   ;;
51
52   f) # generating file; default behaviour
53   GENERATE_FILE='1'
54   ;;
55
56   esac
57   done
58
59 # Generate output/temporary directory name & path, and output file path
60 OUTFILE=""
61 OUTDIRNAME="grml-hwinfo-${DATE}"
62 OUTDIR="${WORKING_DIR}/${OUTDIRNAME}"
63 mkdir "${OUTDIR}" || { echo 'Directory "'${OUTDIR}'" already exists, aborting.'>&2 ; exit 1; }
64
65 if [ -n "$GENERATE_FILE" ] ; then
66    OUTFILE_="${OUTDIR}.tar.bz2"
67    [ -e "${OUTFILE_}" ] && { echo 'File "'${OUTFILE_}'" already exists, aborting.'>&2 ; rm -r "${OUTDIR}"; exit 1; }
68    OUTFILE=${OUTFILE_}
69    touch "${OUTFILE}"
70 fi
71
72 if [ "$(id -u)" != "0" ] ; then
73    NOTROOT=1
74    echo "W: Running without root permissions. Not all data will be collected."
75 fi
76
77 # check whether a binary is available and executable
78 exectest() {
79 if [ -z "$1" ] ; then
80    echo 'Usage: exectest <binary>'>&2
81    return 1
82 else
83    test -e "$(which $1)" && return 0 || return 1
84 fi
85 }
86
87 # echo a list of all disks and their size
88 # taken from http://cvs.debian.org/fai/lib/disk-info
89 diskandsize() {
90     local isdisk major minor blocks device suffix
91     while read major minor blocks device suffix; do
92         isdisk=1
93         # skip ide cdrom
94         [ -f /proc/ide/$device/media ] && grep -q cdrom /proc/ide/$device/media && isdisk=0
95         [ "$isdisk" -eq 1 ] && echo "$device $blocks"
96     done
97 }
98
99 list_disks() {
100 # print only every second entry; used by disk_info
101 i=0
102 for ent in $@; do
103     if [ "$i" -eq 0 ]; then
104         echo $ent
105         i=1
106     else
107         i=0
108     fi
109 done
110 }
111
112 disk_info() {
113     # the variable holds a space separated list of devices and their block size
114     device_size=`grep -E ' cciss/c.d.$| ida/c.d.$| rd/c.d.$| hd.$| sd.$|/disc$' /proc/partitions | diskandsize`
115     # a list of all local disks, without size
116     disklist=`list_disks $device_size`
117 }
118
119
120 cd "${OUTDIR}" || exit 1
121 (
122   [ -n "$GENERATE_FILE" ]      && echo "Output file:      $OUTFILE"
123   [ -n "$GENERATE_DIRECTORY" ] && echo "Output directory: $OUTDIR"
124   echo
125   echo "This might take a few seconds/minutes. Please be patient..."
126
127 # some sysinfo
128   date > date
129   if [ -r /etc/grml_version ] ; then
130      cat /etc/grml_version > grml_version
131   fi
132   if [ -r /etc/debian_version ] ; then
133      cat /etc/debian_version > debian_version
134   fi
135   uname -a > uname
136
137 # disks / devices
138   [ -f /proc/scsi/scsi ] && cat /proc/scsi/scsi > scsi
139   (lspci; lspci -n) | sort > lspci
140   [ -r /proc/bus/pnp ] && lspnp > lspnp
141   [ -r /proc/bus/usb ] && lsusb > lsusb
142   cat /proc/partitions > partitions
143   find /proc/ide/ -name geometry -exec grep . {} \; > proc_ide 2>/dev/null
144   df -h > df 2>/dev/null
145   for i in free lsmod mount lsdev ; do
146       exectest $i  && $i > $i
147   done
148
149 # proc stuff
150   for i in cpuinfo interrupts cmdline devices dma fb iomem ioports \
151     mdstat meminfo modules mtrr pci version ; do
152     [ -r /proc/$i ] && cat /proc/$i > proc_$i
153   done
154   exectest sysdump  && sysdump > sysdump 2>sysdump.error
155 # for sysnet in `find /proc/sys/net/*/ -type f | grep -v flush`; do cat $sysnet >> sysnet ; done
156
157 # log
158   dmesg > dmesg.cur
159
160 # hwinfo
161   exectest discover && discover -v --type-summary --enable-bus all > discover 2> discover.2
162   exectest hwinfo   && hwinfo log=hwinfo
163   exectest x86info  && x86info > x86info 2>x86info.2
164
165 # net stuff
166   exectest ifconfig  && ifconfig -v -a  > ifconfig
167   exectest ip        && ip route show   > ip_route
168   exectest ip        && ip link show    > ip_link
169   exectest route     && route -n        > route
170
171 # software
172   if exectest dpkg ; then
173      dpkg --get-selections   > dpkg_get_selections
174      COLUMNS=300 dpkg --list > dpkg_list
175      COLUMNS=1000 dpkg -l linux-image-$UNAME | grep linux-image-$UNAME | tr -s ' ' > running_kernel
176   fi
177
178 # power management
179   exectest laptop-detect  && laptop-detect >/dev/null 2>/dev/null && echo "0" > laptop_detected
180   exectest acpi_available && acpi_available && cat /proc/acpi/info > acpi_info
181   exectest acpi && acpi > acpi 2> acpi.error && acpi -v > acpi.version
182   [ -r /proc/apm/ ] && apm > apm
183
184 # kernel stuff
185   if [ -r /proc/config.gz ] ; then
186      zcat /proc/config.gz > kernelconfig
187   else
188      [ -r /boot/config-$UNAME ] && cat /boot/config-$UNAME > kernelconfig
189   fi
190
191 # X stuff
192   if [ -n "${DISPLAY}" ] ; then
193      exectest xviddetect  && xviddetect         > xviddetect
194      exectest xvidtune    && xvidtune -show     > xdivtune
195      exectest xrandr      && xrandr             > xrandr
196      exectest xdpyinfo    && xdpyinfo           > xdpyinfo
197      X -version > x_version 2>&1
198   fi
199
200   for i in Xorg.0.log Xorg.7.log Xorg.8.log XFree86.0.log XFree86.7.log XFree86.8.log dmesg ; do
201       cp /var/log/$i log_$i 2>/dev/null
202   done
203
204   cp /etc/X11/xorg.conf    xorg.conf    2>/dev/null
205   cp /etc/modules          modules      2>/dev/null
206   cp /etc/X11/XF86Config-4 XF86Config-4 2>/dev/null
207
208 # not available:
209 # sysinfo -class device -level all
210
211 # as root:
212 if [ -n "$NOTROOT" ] ; then
213    echo "not running as root" > root
214 else
215    echo "running as root" > root
216    disk_info
217    exectest sfdisk     && sfdisk -d > sfdisk 2>sfdisk.error
218    exectest ddcprobe   && ddcprobe  > ddcprobe
219    exectest dmidecode  && dmidecode > dmidecode
220
221    exectest dconf && dconf -o dconf
222
223    if [ -x /usr/share/doc/lm-sensors/examples/eeprom/decode-dimms.pl ] ; then
224       /usr/share/doc/lm-sensors/examples/eeprom/decode-dimms.pl > decode-dimms 2>decode-dimms.error
225    fi
226
227    for disk in $disklist; do
228       exectest smartctl  && echo "smartctl -a /dev/$disk :\n" >> smartctl && smartctl -a /dev/$disk       >> smartctl             && echo "\n\n" >> smartctl
229       exectest hdparm    && echo "hdparm -iv  /dev/$disk :\n" >> hdparm   && hdparm -iv  /dev/$disk       >> hdparm               && echo "\n\n" >> hdparm
230       exectest fdisk     && echo "fdisk -lu   /dev/$disk :\n" >> fdisk    && fdisk -lu   /dev/$disk       >> fdisk 2>>fdisk.error && echo "\n\n" >> fdisk
231       exectest parted    && echo "parted -s   /dev/$disk :\n" >> parted   && parted -s   /dev/$disk print >> parted               && echo "\n\n" >> parted
232       LC_ALL=C file -s /dev/$disk?* | grep -v ": empty" >> file_disk
233    done
234 fi
235 )
236
237 echo
238
239 cd "${WORKING_DIR}"
240
241 # create tarball
242 if [ -n "$GENERATE_FILE" ] ; then
243   tar jcf "${OUTFILE}" "${OUTDIRNAME}"
244   [ -r "$OUTFILE" ] && echo "$OUTFILE ("$(ls -ahl "$OUTFILE" | awk '{print $5}')") has been generated."
245 fi
246
247 # remove (temporary) output directory if needed, else keep it, as it doubles
248 # as the real output directory.
249 if [ -z "$GENERATE_DIRECTORY" ] ; then
250   rm -r "${OUTDIR}"
251 else
252   [ -r "${OUTDIR}" ] && echo "${OUTDIR} has been generated."
253 fi
254
255 exit 0
256
257 ## END OF FILE##################################################################