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