tazpanel view hardware.cgi @ rev 597

hardware.cgi: read pci.ids (again)
author Pascal Bellard <pascal.bellard@slitaz.org>
date Thu Aug 04 12:46:40 2016 +0200 (2016-08-04)
parents 05203af2f9b4
children 8afba0061740
line source
1 #!/bin/sh
2 #
3 # Hardware part of TazPanel - Devices, drivers, printing
4 #
5 # Copyright (C) 2011-2015 SliTaz GNU/Linux - BSD License
6 #
8 # Common functions from libtazpanel
9 . lib/libtazpanel
10 get_config
11 header
13 TITLE=$(_ 'Hardware')
15 # Call an optional module
16 lib() {
17 module=lib/$1
18 shift
19 [ -s $module ] && . $module "$@"
20 }
22 disk_info() {
23 fdisk -l | fgrep Disk | while read a b c; do
24 d=${b#/dev/}
25 d="/sys/block/${d%:}/device"
26 [ -d $d ] && echo "$a $b $c, $(cat $d/vendor) $(cat $d/model)"
27 done 2> /dev/null | sed 's/ */ /g'
28 }
30 lsusb_vd() {
31 if lsusb --help 2>&1 | grep -qi busybox ; then
32 for i in /sys/class/usb_device/*/device ; do
33 grep -qs ${1%:*} $i/idVendor || continue
34 grep -qs ${1#*:} $i/idProduct || continue
35 ( cd $i ; for j in * ; do
36 [ -f $j -a -r $j ] || continue
37 case "$j" in
38 descriptors|remove) continue
39 esac
40 awk -vn=$j '{printf "%-20s %s\n",n,$0;n=""}' <$j
41 done )
42 break
43 done
44 else
45 lsusb -vd $1 | syntax_highlighter lsusb
46 fi
47 }
49 lsusb_table() {
50 cat <<EOT
51 <table class="wide zebra">
52 <thead>
53 <tr>
54 <td>$(_ 'Bus')</td>
55 <td>$(_ 'Device')</td>
56 <td>$(_ 'ID')</td>
57 <td>$(_ 'Name')</td>
58 </tr>
59 </thead>
60 <tbody>
61 EOT
62 lsusb | while read x b y d z id name ; do
63 echo "<tr><td>$b</td><td>${d%:}</td><td><a href=\"?lsusb=$id"
64 p=$(printf "class/usb_device/usbdev%d.%d" $b ${d%:})
65 grep -qs 0 /sys/$p/device/authorized && id="<del>$id</del>"
66 echo "\">$id</td><td>${name:-$(sed 's/ .*//' /sys/$p/device/manufacturer) $(cat /sys/$p/device/product)}</td></tr>"
67 done
68 echo "</tbody></table>"
69 }
72 lspci_table() {
73 cat <<EOT
74 <table class="wide zebra">
75 <thead><tr>
76 <td>$(_ 'Slot')</td>
77 <td>$(_ 'Device')</td>
78 <td>$(_ 'Name')</td>
79 </tr></thead>
80 <tbody>
81 EOT
82 lspci | while read a b c id ; do
83 if [ $b != "Class" ] || [ ! -s /usr/share/misc/pci.ids.gz ]; then
84 echo "X$a $b $c $id"
85 continue
86 fi
87 echo -n "$a "
88 zcat /usr/share/misc/pci.ids.gz | \
89 awk -va=${c:0:2} -vb=${c:2:2} -vh=${id:0:4} -vl=${id:5:4} '{
90 if ($1 == "C" && $2 == a) class=substr($0,5)
91 if (class != "" && $1 == b) { class=substr($0,5); exit }
92 if (substr($0,1,4) == h) m=substr($0,7)
93 else if (m == "") next
94 else if (substr($0,2,4) == l) { name=m substr($0,7); m="" }
95 else if ($1 == h && $2 == l) { name=m substr($0,14); m="" }
96 } END { print class ": " name }'
97 done | sed 's| |</td><td>|;
98 s|: |</td><td>|;
99 s|^X\([^<]*\)|<a href="?lspci=\1">\1</a>|;
100 s|^.*$|<tr><td>\0</td></tr>|'
101 echo "</tbody></table>"
102 }
105 #
106 # Commands
107 #
109 case " $(GET) " in
110 *\ print\ *)
111 xhtml_header
112 echo "<h2>TODO</h2>"
113 ;;
116 *\ tazx\ *)
117 xhtml_header
118 cat <<EOT
119 <pre>$(tazx auto)</pre>
120 EOT
121 ;;
124 *\ detect\ *)
125 # Front end for Tazhw
126 # TODO: Add button to detect webcam, etc. Like in tazhw box.
127 xhtml_header "$(_ 'Detect hardware')"
128 cat <<EOT
129 <p>$(_ 'Detect PCI and USB hardware')</p>
130 EOT
131 tazhw detect-pci | htmlize
132 tazhw detect-usb | htmlize | filter_taztools_msgs
133 ;;
136 *\ modules\ *|*\ modinfo\ *)
137 xhtml_header "$(_ 'Kernel modules')"
139 search="$(GET search)"
140 cat <<EOT
141 <p>$(_ 'Manage, search or get information about the Linux kernel modules')</p>
143 <form class="search">
144 <input type="hidden" name="modules"/>
145 <input type="search" name="search" value="$search" placeholder="$(_ 'Modules search')" results="5" autosave="modsearch" autocomplete="on"/>
146 <button type="submit">$(_n 'Search')</button>
147 </form>
148 EOT
149 # Request may be modinfo output that we want in the page itself
150 get_modinfo="$(GET modinfo)"
151 if [ -n "$get_modinfo" ]; then
152 cat <<EOT
153 <section>
154 <header>$(_ 'Detailed information for module: %s' $get_modinfo)</header>
155 <div class="scroll">
157 EOT
158 modinfo $get_modinfo | awk 'BEGIN{print "<table class=\"wide zebra\">"}
159 {
160 printf("<tr><td><b>%s</b></td>", $1)
161 $1=""; printf("<td>%s</td></tr>", $0)
162 }
163 END{print "</table></div></section>"}'
164 fi
166 if [ -n "$(GET modprobe)" ]; then
167 echo "<pre>$(modprobe -v $(GET modprobe))</pre>"
168 fi
169 if [ -n "$(GET rmmod)" ]; then
170 echo "Removing"
171 rmmod -w $(GET rmmod)
172 fi
174 # Module search
175 if [ -n "$search" ]; then
176 cat <<EOT
177 <section>
178 <header>$(_ 'Matching result(s) for: %s' $search)</header>
179 <pre class="scroll">
180 EOT
181 busybox modprobe -l | grep "$search" | while read line
182 do
183 name=$(basename $line)
184 mod=${name%.ko.xz}
185 echo "<span data-icon=\"@modules@\">$(_ 'Module:')</span> <a href='?modinfo=$mod'>$mod</a>"
186 done
187 echo '</pre></section>'
188 fi
190 cat <<EOT
191 <section>
192 <table class="zebra">
193 <thead>
194 <tr>
195 <td>$(_ 'Module')</td>
196 <td>$(_ 'Description')</td>
197 <td>$(_ 'Size')</td>
198 <td>$(_ 'Used')</td>
199 <td>$(_ 'by')</td>
200 </tr>
201 <thead>
202 <tbody>
203 EOT
204 # Get the list of modules and link to modinfo
205 lsmod | tail -n+2 | awk '{
206 gsub(",", " ", $4);
207 printf("<tr><td><a href=\"?modinfo=%s\">%s</a></td><td>", $1, $1);
208 system("modinfo -d " $1);
209 printf("</td><td>%s</td><td>%s</td><td>%s</td></tr>", $2, $3, $4);
210 }'
211 cat <<EOT
212 </thead>
213 </table>
214 </section>
215 EOT
216 ;;
219 *\ lsusb\ *)
220 xhtml_header
221 vidpid="$(GET lsusb)"
222 cat <<EOT
223 <h2>$(_ 'Information for USB Device %s' $vidpid)</h2>
225 <p>$(_ 'Detailed information about specified device.')</p>
227 <section>$(lsusb_table)</section>
228 EOT
229 [ "$vidpid" != 'lsusb' ] && cat <<EOT
230 <section>
231 <pre style="white-space: pre-wrap">$(lsusb_vd $vidpid)</pre>
232 </section>
233 EOT
234 ;;
237 *\ lspci\ *)
238 xhtml_header
239 slot="$(GET lspci)"
240 cat <<EOT
241 <h2>$(_ 'Information for PCI Device %s' $slot)</h2>
243 <p>$(_ 'Detailed information about specified device.')</p>
245 <section>$(lspci_table)</section>
246 EOT
247 [ "$slot" != 'lspci' ] && cat <<EOT
248 <section>
249 <pre style="white-space: pre-wrap">$(lspci -vs $slot | syntax_highlighter lspci)</pre>
250 </section>
251 EOT
252 ;;
255 *)
256 [ -n "$(GET brightness)" ] &&
257 echo -n $(GET brightness) > /sys/devices/virtual/backlight/$(GET dev)/brightness
259 #
260 # Default to summary with mounted filesystem, loaded modules
261 #
262 xhtml_header "$(_ 'Drivers &amp; Devices')"
263 cat <<EOT
264 <p>$(_ 'Manage your computer hardware')</p>
266 <form><!--
267 --><button name="modules" data-icon="@modules@">$(_ 'Kernel modules')</button><!--
268 --><button name="detect" data-icon="@detect@" data-root>$(_ 'Detect PCI/USB')</button><!--
269 --><button name="tazx" data-icon="@tazx@" data-root>$(_ 'Auto-install Xorg video driver')</button><!--
270 --></form>
272 EOT
275 # Battery state
276 if [ -n "$(ls /proc/acpi/battery/*/info 2>/dev/null)" ]; then
277 cat <<EOT
278 <section>
279 <header>$(_ 'Battery')</header>
280 <div>
281 <table class="wide">
282 EOT
283 for dev in /proc/acpi/battery/*; do
284 grep ^present $dev/info | grep -q yes || continue
285 design=$(sed '/design capacity:/!d; s/[^0-9]*\([0-9]*\).*/\1/' < $dev/info)
286 remain=$(sed '/remaining capacity/!d; s/[^0-9]*\([0-9]*\).*/\1/' < $dev/state)
287 rate=$(sed '/present rate/!d; s/[^0-9]*\([0-9]*\).*/\1/' < $dev/state)
288 full=$(sed '/last full capacity/!d; s/[^0-9]*\([0-9]*\).*/\1/' < $dev/info)
289 warning=$(sed '/design capacity warning/!d;s/[^0-9]*\([0-9]*\).*/\1/' < $dev/info)
290 low=$(sed '/design capacity low/!d; s/[^0-9]*\([0-9]*\).*/\1/' < $dev/info)
291 state=$(sed '/charging state/!d; s/\([^:]*:[ ]\+\)\([a-z]\+\)/\2/' < $dev/state)
293 rempct=$(( $remain * 100 / $full ))
294 cat <<EOT
295 <tr>
296 <td><span data-icon="@battery@">$(_ 'Battery')</span>
297 $(grep "^battery type" $dev/info | sed 's/.*: *//')
298 $(grep "^design capacity:" $dev/info | sed 's/.*: *//') </td>
299 <td>$(_ 'health') $(( (100*$full)/$design))%</td>
300 <td class="meter"><meter min="0" max="$full" value="$remain" low="$low"
301 high="$warning" optimum="$full"></meter>
302 <span>
303 EOT
304 case "$state" in
305 "discharging")
306 remtime=$(( $remain * 60 / $rate ))
307 remtimef=$(printf "%d:%02d" $(($remtime/60)) $(($remtime%60)))
308 _ 'Discharging %d%% - %s' $rempct $remtimef ;;
309 "charging")
310 remtime=$(( ($full - $remain) * 60 / $rate ))
311 remtimef=$(printf "%d:%02d" $(($remtime/60)) $(($remtime%60)))
312 _ 'Charging %d%% - %s' $rempct $remtimef ;;
313 "charged")
314 _ 'Charged 100%%' ;;
315 esac
316 cat <<EOT
318 </span>
319 </td>
320 </tr>
321 EOT
322 done
323 cat <<EOT
324 </table>
325 </div>
326 </section>
327 EOT
328 fi
331 # Thermal sensors
332 if [ -n "$(ls /sys/devices/virtual/thermal/*/temp 2>/dev/null)" ]; then
333 echo "<p><span data-icon=\"@temperature@\">$(_ 'Temperature:')</span>"
334 for temp in /sys/devices/virtual/thermal/*/temp; do
335 awk '{ print $1/1000 "℃" }' < $temp
336 done
337 echo '</p>'
338 fi
341 # Brightness
342 if [ -n "$(ls /sys/devices/virtual/backlight/*/brightness 2>/dev/null)" ]; then
343 echo '<form>'
344 for dev in /sys/devices/virtual/backlight/*/brightness; do
345 name=$(echo $dev | sed 's|.*/backlight/\([^/]*\).*|\1|')
346 cat <<EOT
347 <input type="hidden" name="dev" value="$name"/>
348 <span data-icon="@brightness@">$(_ 'Brightness')</span> \
349 $(sed 's/.*\.//;s/_*$//' < /sys/devices/virtual/backlight/$name/device/path):
350 <select name="brightness" onchange="submit();">
351 EOT
352 max=$(cat /sys/devices/virtual/backlight/$name/max_brightness)
353 for i in $(seq 0 $max); do
354 echo -n "<option value=\"$i\""
355 [ $i -eq $(cat /sys/devices/virtual/backlight/$name/actual_brightness) ] &&
356 echo -n " selected=\"selected\""
357 echo "> $(( (($i + 1) * 100) / ($max + 1) ))% </option>"
358 done
359 echo '</select>'
360 done
361 echo '</form>'
362 fi
365 cat <<EOT
366 <section>
367 <form action="#mount" class="wide">
368 <header id="disk">$(_ 'Filesystem usage statistics')</header>
369 <div>
370 <pre>$(disk_info)</pre>
371 </div>
372 EOT
375 #
376 # Loop device management actions
377 #
378 device=$(GET loopdev)
379 lib crypto $device
380 case "$device" in
381 /dev/*loop*)
382 set -- $(losetup | grep ^$device:)
383 [ -n "$3" ] && losetup -d $device
384 ro=""
385 [ -n "$(GET readonly)" ] && ro="-r"
386 file="$(GET backingfile)"
387 [ -n "$file" ] && losetup -o $(GET offset) $ro $device $file
388 esac
391 #
392 # Disk stats and management (mount, umount, check)
393 #
394 device=$(GET device)
395 lib crypto $device
396 case "$device" in
397 *[\;\`\&\|\$]*) ;;
398 mount\ *)
399 ro=""
400 [ -n "$(GET readonly)" ] && ro="-r"
401 mntdir="$(GET mountpoint)"
402 [ -d "$mntdir" ] || mkdir -p "$mntdir"
403 $device $ro "$mntdir";;
404 umount\ *|swapon\ *|swapoff\ *)
405 $device ;;
406 esac
407 cat <<EOT
408 <table id="mount" class="zebra wide center">
409 EOT
410 df_thead
411 echo '<tbody>'
412 for fs in $(blkid | sort | sed 's/:.*//'); do
413 set -- $(df -h | grep "^$fs ")
414 size=$2
415 used=$3
416 av=$4
417 grep "^$fs " /proc/mounts | grep -q "[, ]ro[, ]" &&
418 av="<del>$av</del>"
419 pct=$5
420 mp=$6
422 # action
423 action="mount"
424 [ -n "$mp" ] && action="umount"
425 type=$(blkid $fs | sed '/ TYPE=/!d;s/.* TYPE="\([^"]*\).*/\1/')
426 [ -n "$type" ] || continue
427 [ "$type" == "swap" ] && action="swapon"
428 if grep -q "^$fs " /proc/swaps; then
429 action="swapoff"
430 set -- $(grep "^$fs " /proc/swaps)
431 size=$(blk2h $(($3*2)))
432 used=$(blk2h $(($4*2)))
433 av=$(blk2h $((2*($3-$4))))
434 pct=$(((100*$4)/$3))%
435 mp=swap
436 fi
438 # size
439 [ -z "$size" ] &&
440 size="$(blk2h $(cat /sys/block/${fs#/dev/}/size /sys/block/*/${fs#/dev/}/size))"
442 # image
443 disktype="@hdd@"
444 case "$(cat /sys/block/${fs#/dev/}/removable 2>/dev/null ||
445 cat /sys/block/${fs:5:3}/removable 2>/dev/null)" in
446 1) disktype="@removable@" ;;
447 esac
448 case "$(cat /sys/block/${fs#/dev/}/ro 2>/dev/null ||
449 cat /sys/block/${fs:5:3}/ro 2>/dev/null)" in
450 1) disktype="@cd@" ;;
451 esac
453 radio="<input type=\"radio\" name=\"device\" value=\"$action $fs\" id=\"${fs#/dev/}\"/>"
454 [ "$REMOTE_USER" == "root" ] || radio=""
455 cat <<EOT
456 <tr>
457 <td>$radio<!--
458 --><label for="${fs#/dev/}" data-icon="$disktype">&thinsp;${fs#/dev/}</label></td>
459 <td>$(blkid $fs | sed '/LABEL=/!d;s/.*LABEL="\([^"]*\).*/\1/')</td>
460 <td>$type</td>
461 <td>$size</td>
462 <td>$av</td>
463 EOT
464 if [ -n "$pct" ]; then
465 cat <<EOT
466 <td class="meter"><meter min="0" max="100" value="${pct%%%}" low="70"
467 high="90" optimum="10"></meter>
468 <span>$used - $pct</span>
469 </td>
470 EOT
471 else
472 cat <<EOT
473 <td> </td>
474 EOT
475 fi
476 cat <<EOT
477 <td>$mp</td>
478 <td>$(blkid $fs | sed '/UUID=/!d;s/.*UUID="\([^"]*\).*/\1/')</td>
479 </tr>
480 EOT
481 done
482 cat <<EOT
483 </tbody>
484 </table>
485 EOT
486 [ "$REMOTE_USER" == "root" ] && cat <<EOT
487 $(lib crypto input)
489 <footer>
490 <button type="submit">mount / umount</button> -
491 $(_ 'new mount point:') <input type="text" name="mountpoint" value="/media/usbdisk"/> -
492 <input type="checkbox" name="readonly" id="ro"><label for="ro">&thinsp;$(_ 'read-only')</label>
493 </footer>
494 EOT
495 cat <<EOT
496 </form>
497 </section>
498 EOT
501 #
502 # /etc/fstab
503 #
504 cat <<EOT
505 <section>
506 <header>
507 $(_ 'Filesystems table')
508 $(edit_button /etc/fstab)
509 </header>
510 <table class="wide zebra center">
511 <thead>
512 <tr>
513 <td>$(_ 'Disk')</td>
514 <td>$(_ 'Mount point')</td>
515 <td>$(_ 'Type')</td>
516 <td>$(_ 'Options')</td>
517 <td>$(_ 'Freq')</td>
518 <td>$(_ 'Pass')</td>
519 </tr>
520 </thead>
521 <tbody>
522 EOT
524 grep -v '^#' /etc/fstab | awk '{
525 print "<tr><td>" $1 "</td><td>" $2 "</td><td>" $3 "</td><td>" $4
526 print "</td><td>" $5 "</td><td>" $6 "</td></tr>"
527 }
528 END{print "</tbody></table>"}'
530 cat <<EOT
531 </section>
532 EOT
535 #
536 # Loop device management GUI
537 #
538 cat <<EOT
539 <section>
540 <header>$(_ 'Loop devices')</header>
542 <form action="#loop" class="wide">
543 <div class="scroll">
544 <table id="loop" class="wide zebra scroll">
545 <thead>
546 <tr>
547 <td>$(_ 'Device')</td>
548 <td>$(_ 'Backing file')</td>
549 <td>$(_ 'Size')</td>
550 <td>$(_ 'Access')</td>
551 <td>$(_ 'Offset')</td>
552 </tr>
553 </thead>
554 <tbody>
555 EOT
556 for devloop in $(ls /dev/*loop[0-9]*); do
557 loop="${devloop#/dev/}"
558 dir=/sys/block/$loop
559 case "$(cat $dir/ro 2>/dev/null)" in
560 0) ro="$(_ "read/write")" ;;
561 1) ro="$(_ "read only")" ;;
562 *) ro="" ;;
563 esac
564 size=$(blk2h $(cat $dir/size))
565 [ "$size" == "0.0K" ] && size="" && ro=""
566 set -- $(losetup $devloop)
567 set -- "${3:-$(cat $dir/loop/backing_file)}" "${2:-$(cat $dir/loop/offset)}" ${ro// /&nbsp;}
568 cat <<EOT
569 <tr><td><input type="radio" name="loopdev" value="$devloop" id="$loop"/><!--
570 --><label for="$loop" data-icon="@loopback@">$loop</label></td>
571 <td>$1</td><td>$size</td><td align="center">$3</td><td align="right">$2</td>
572 </tr>
573 EOT
574 done
575 cat <<EOT
576 </tbody>
577 </table>
578 </div>
580 $(lib crypto input)
582 <footer>
583 <button type="submit" data-icon="@ok@">$(_ 'Setup')</button> -
584 $(_ 'new backing file:') <input type="text" name="backingfile"/> -
585 $(_ 'offset in bytes:') <input type="text" name="offset" value="0" size="8"/> -
586 <input type="checkbox" name="readonly" id="ro"/><label for="ro">$(_ 'read only')</label>
587 </footer>
588 </form>
589 </section>
590 EOT
593 #
594 # System memory
595 #
596 mem_total=$(free -m | awk '$1 ~ "M" {print $2}')
597 mem_used=$((100 * $(free -m | awk '$1 ~ "+" {print $3}') / mem_total))
598 mem_buff=$((100 * $(free -m | awk '$1 ~ "M" {print $6}') / mem_total))
599 mem_free=$((100 - mem_used - mem_buff))
601 cat <<EOT
602 <section>
603 <header>$(_ 'System memory')</header>
605 <div class="sysmem"><!--
606 --><span class="sysmem_used" style="width: ${mem_used}%" title="$(_ 'Used')" ><span>${mem_used}%</span></span><!--
607 EOT
608 [ $mem_buff != 0 ] && cat <<EOT
609 --><span class="sysmem_buff" style="width: ${mem_buff}%" title="$(_ 'Buffers')"><span>${mem_buff}%</span></span><!--
610 EOT
611 cat <<EOT
612 --><span class="sysmem_free" style="width: ${mem_free}%" title="$(_ 'Free')" ><span>${mem_free}%</span></span><!--
613 --></div>
615 <table class="wide zebra center">
616 <thead>
617 <tr>
618 <td>&nbsp;</td>
619 <td>total</td>
620 <td>used</td>
621 <td>free</td>
622 <td>shared</td>
623 <td>buffers</td>
624 </tr>
625 </thead>
626 <tbody>
627 EOT
629 free -m | awk '
630 $1 ~ "M" {print "<tr><td>"$1"</td><td>"$2"</td><td>"$3"</td><td>"$4"</td><td>"$5"</td><td>"$6"</td></tr>"}
631 $1 ~ "+" {print "<tr><td>"$1 $2"</td><td></td><td>"$3"</td><td>"$4"</td><td></td><td></td></tr>"}
632 $1 ~ "S" {print "<tr><td>"$1"</td><td>"$2"</td><td>"$3"</td><td>"$4"</td><td></td><td></td></tr>"}'
634 cat <<EOT
635 </tbody>
636 </table>
637 </section>
638 EOT
641 #
642 # lspci and lsusb summary tables
643 #
644 cat <<EOT
645 <section>
646 <header>lspci</header>
647 $(lspci_table)
648 </section>
651 <section>
652 <header>lsusb</header>
653 $(lsusb_table)
654 </section>
655 EOT
656 ;;
657 esac
659 xhtml_footer
660 exit 0