tazpanel view hardware.cgi @ rev 627

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