tazpanel view hardware.cgi @ rev 592

Hide procps's "ps" warning (on boot log and more) like: "Unknown HZ value! (70) Assume 100."
author Aleksej Bobylev <al.bobylev@gmail.com>
date Mon May 23 16:31:22 2016 +0300 (2016-05-23)
parents d04d60d1892d
children 05203af2f9b4
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 | sed 's| |</td><td>|;
83 s|: |</td><td>|;
84 s|^\([^<]*\)|<a href="?lspci=\1">\1</a>|;
85 s|^.*$|<tr><td>\0</td></tr>|'
86 echo "</tbody></table>"
87 }
90 #
91 # Commands
92 #
94 case " $(GET) " in
95 *\ print\ *)
96 xhtml_header
97 echo "<h2>TODO</h2>"
98 ;;
101 *\ tazx\ *)
102 xhtml_header
103 cat <<EOT
104 <pre>$(tazx auto)</pre>
105 EOT
106 ;;
109 *\ detect\ *)
110 # Front end for Tazhw
111 # TODO: Add button to detect webcam, etc. Like in tazhw box.
112 xhtml_header "$(_ 'Detect hardware')"
113 cat <<EOT
114 <p>$(_ 'Detect PCI and USB hardware')</p>
115 EOT
116 tazhw detect-pci | htmlize
117 tazhw detect-usb | htmlize | filter_taztools_msgs
118 ;;
121 *\ modules\ *|*\ modinfo\ *)
122 xhtml_header "$(_ 'Kernel modules')"
124 search="$(GET search)"
125 cat <<EOT
126 <p>$(_ 'Manage, search or get information about the Linux kernel modules')</p>
128 <form class="search">
129 <input type="hidden" name="modules"/>
130 <input type="search" name="search" value="$search" placeholder="$(_ 'Modules search')" results="5" autosave="modsearch" autocomplete="on"/>
131 <button type="submit">$(_n 'Search')</button>
132 </form>
133 EOT
134 # Request may be modinfo output that we want in the page itself
135 get_modinfo="$(GET modinfo)"
136 if [ -n "$get_modinfo" ]; then
137 cat <<EOT
138 <section>
139 <header>$(_ 'Detailed information for module: %s' $get_modinfo)</header>
140 <div class="scroll">
142 EOT
143 modinfo $get_modinfo | awk 'BEGIN{print "<table class=\"wide zebra\">"}
144 {
145 printf("<tr><td><b>%s</b></td>", $1)
146 $1=""; printf("<td>%s</td></tr>", $0)
147 }
148 END{print "</table></div></section>"}'
149 fi
151 if [ -n "$(GET modprobe)" ]; then
152 echo "<pre>$(modprobe -v $(GET modprobe))</pre>"
153 fi
154 if [ -n "$(GET rmmod)" ]; then
155 echo "Removing"
156 rmmod -w $(GET rmmod)
157 fi
159 # Module search
160 if [ -n "$search" ]; then
161 cat <<EOT
162 <section>
163 <header>$(_ 'Matching result(s) for: %s' $search)</header>
164 <pre class="scroll">
165 EOT
166 busybox modprobe -l | grep "$search" | while read line
167 do
168 name=$(basename $line)
169 mod=${name%.ko.xz}
170 echo "<span data-icon=\"@modules@\">$(_ 'Module:')</span> <a href='?modinfo=$mod'>$mod</a>"
171 done
172 echo '</pre></section>'
173 fi
175 cat <<EOT
176 <section>
177 <table class="zebra">
178 <thead>
179 <tr>
180 <td>$(_ 'Module')</td>
181 <td>$(_ 'Description')</td>
182 <td>$(_ 'Size')</td>
183 <td>$(_ 'Used')</td>
184 <td>$(_ 'by')</td>
185 </tr>
186 <thead>
187 <tbody>
188 EOT
189 # Get the list of modules and link to modinfo
190 lsmod | tail -n+2 | awk '{
191 gsub(",", " ", $4);
192 printf("<tr><td><a href=\"?modinfo=%s\">%s</a></td><td>", $1, $1);
193 system("modinfo -d " $1);
194 printf("</td><td>%s</td><td>%s</td><td>%s</td></tr>", $2, $3, $4);
195 }'
196 cat <<EOT
197 </thead>
198 </table>
199 </section>
200 EOT
201 ;;
204 *\ lsusb\ *)
205 xhtml_header
206 vidpid="$(GET lsusb)"
207 cat <<EOT
208 <h2>$(_ 'Information for USB Device %s' $vidpid)</h2>
210 <p>$(_ 'Detailed information about specified device.')</p>
212 <section>$(lsusb_table)</section>
213 EOT
214 [ "$vidpid" != 'lsusb' ] && cat <<EOT
215 <section>
216 <pre style="white-space: pre-wrap">$(lsusb_vd $vidpid)</pre>
217 </section>
218 EOT
219 ;;
222 *\ lspci\ *)
223 xhtml_header
224 slot="$(GET lspci)"
225 cat <<EOT
226 <h2>$(_ 'Information for PCI Device %s' $slot)</h2>
228 <p>$(_ 'Detailed information about specified device.')</p>
230 <section>$(lspci_table)</section>
231 EOT
232 [ "$slot" != 'lspci' ] && cat <<EOT
233 <section>
234 <pre style="white-space: pre-wrap">$(lspci -vs $slot | syntax_highlighter lspci)</pre>
235 </section>
236 EOT
237 ;;
240 *)
241 [ -n "$(GET brightness)" ] &&
242 echo -n $(GET brightness) > /sys/devices/virtual/backlight/$(GET dev)/brightness
244 #
245 # Default to summary with mounted filesystem, loaded modules
246 #
247 xhtml_header "$(_ 'Drivers &amp; Devices')"
248 cat <<EOT
249 <p>$(_ 'Manage your computer hardware')</p>
251 <form><!--
252 --><button name="modules" data-icon="@modules@">$(_ 'Kernel modules')</button><!--
253 --><button name="detect" data-icon="@detect@" data-root>$(_ 'Detect PCI/USB')</button><!--
254 --><button name="tazx" data-icon="@tazx@" data-root>$(_ 'Auto-install Xorg video driver')</button><!--
255 --></form>
257 EOT
260 # Battery state
261 if [ -n "$(ls /proc/acpi/battery/*/info 2>/dev/null)" ]; then
262 cat <<EOT
263 <section>
264 <header>$(_ 'Battery')</header>
265 <div>
266 <table class="wide">
267 EOT
268 for dev in /proc/acpi/battery/*; do
269 grep ^present $dev/info | grep -q yes || continue
270 design=$(sed '/design capacity:/!d; s/[^0-9]*\([0-9]*\).*/\1/' < $dev/info)
271 remain=$(sed '/remaining capacity/!d; s/[^0-9]*\([0-9]*\).*/\1/' < $dev/state)
272 rate=$(sed '/present rate/!d; s/[^0-9]*\([0-9]*\).*/\1/' < $dev/state)
273 full=$(sed '/last full capacity/!d; s/[^0-9]*\([0-9]*\).*/\1/' < $dev/info)
274 warning=$(sed '/design capacity warning/!d;s/[^0-9]*\([0-9]*\).*/\1/' < $dev/info)
275 low=$(sed '/design capacity low/!d; s/[^0-9]*\([0-9]*\).*/\1/' < $dev/info)
276 state=$(sed '/charging state/!d; s/\([^:]*:[ ]\+\)\([a-z]\+\)/\2/' < $dev/state)
278 rempct=$(( $remain * 100 / $full ))
279 cat <<EOT
280 <tr>
281 <td><span data-icon="@battery@">$(_ 'Battery')</span>
282 $(grep "^battery type" $dev/info | sed 's/.*: *//')
283 $(grep "^design capacity:" $dev/info | sed 's/.*: *//') </td>
284 <td>$(_ 'health') $(( (100*$full)/$design))%</td>
285 <td class="meter"><meter min="0" max="$full" value="$remain" low="$low"
286 high="$warning" optimum="$full"></meter>
287 <span>
288 EOT
289 case "$state" in
290 "discharging")
291 remtime=$(( $remain * 60 / $rate ))
292 remtimef=$(printf "%d:%02d" $(($remtime/60)) $(($remtime%60)))
293 _ 'Discharging %d%% - %s' $rempct $remtimef ;;
294 "charging")
295 remtime=$(( ($full - $remain) * 60 / $rate ))
296 remtimef=$(printf "%d:%02d" $(($remtime/60)) $(($remtime%60)))
297 _ 'Charging %d%% - %s' $rempct $remtimef ;;
298 "charged")
299 _ 'Charged 100%%' ;;
300 esac
301 cat <<EOT
303 </span>
304 </td>
305 </tr>
306 EOT
307 done
308 cat <<EOT
309 </table>
310 </div>
311 </section>
312 EOT
313 fi
316 # Thermal sensors
317 if [ -n "$(ls /sys/devices/virtual/thermal/*/temp 2>/dev/null)" ]; then
318 echo "<p><span data-icon=\"@temperature@\">$(_ 'Temperature:')</span>"
319 for temp in /sys/devices/virtual/thermal/*/temp; do
320 awk '{ print $1/1000 "℃" }' < $temp
321 done
322 echo '</p>'
323 fi
326 # Brightness
327 if [ -n "$(ls /sys/devices/virtual/backlight/*/brightness 2>/dev/null)" ]; then
328 echo '<form>'
329 for dev in /sys/devices/virtual/backlight/*/brightness; do
330 name=$(echo $dev | sed 's|.*/backlight/\([^/]*\).*|\1|')
331 cat <<EOT
332 <input type="hidden" name="dev" value="$name"/>
333 <span data-icon="@brightness@">$(_ 'Brightness')</span> \
334 $(sed 's/.*\.//;s/_*$//' < /sys/devices/virtual/backlight/$name/device/path):
335 <select name="brightness" onchange="submit();">
336 EOT
337 max=$(cat /sys/devices/virtual/backlight/$name/max_brightness)
338 for i in $(seq 0 $max); do
339 echo -n "<option value=\"$i\""
340 [ $i -eq $(cat /sys/devices/virtual/backlight/$name/actual_brightness) ] &&
341 echo -n " selected=\"selected\""
342 echo "> $(( (($i + 1) * 100) / ($max + 1) ))% </option>"
343 done
344 echo '</select>'
345 done
346 echo '</form>'
347 fi
350 cat <<EOT
351 <section>
352 <form action="#mount" class="wide">
353 <header id="disk">$(_ 'Filesystem usage statistics')</header>
354 <div>
355 <pre>$(disk_info)</pre>
356 </div>
357 EOT
360 #
361 # Loop device management actions
362 #
363 device=$(GET loopdev)
364 lib crypto $device
365 case "$device" in
366 /dev/*loop*)
367 set -- $(losetup | grep ^$device:)
368 [ -n "$3" ] && losetup -d $device
369 ro=""
370 [ -n "$(GET readonly)" ] && ro="-r"
371 file="$(GET backingfile)"
372 [ -n "$file" ] && losetup -o $(GET offset) $ro $device $file
373 esac
376 #
377 # Disk stats and management (mount, umount, check)
378 #
379 device=$(GET device)
380 lib crypto $device
381 case "$device" in
382 *[\;\`\&\|\$]*) ;;
383 mount\ *)
384 ro=""
385 [ -n "$(GET readonly)" ] && ro="-r"
386 mntdir="$(GET mountpoint)"
387 [ -d "$mntdir" ] || mkdir -p "$mntdir"
388 $device $ro "$mntdir";;
389 umount\ *|swapon\ *|swapoff\ *)
390 $device ;;
391 esac
392 cat <<EOT
393 <table id="mount" class="zebra wide center">
394 EOT
395 df_thead
396 echo '<tbody>'
397 for fs in $(blkid | sort | sed 's/:.*//'); do
398 set -- $(df -h | grep "^$fs ")
399 size=$2
400 used=$3
401 av=$4
402 grep "^$fs " /proc/mounts | grep -q "[, ]ro[, ]" &&
403 av="<del>$av</del>"
404 pct=$5
405 mp=$6
407 # action
408 action="mount"
409 [ -n "$mp" ] && action="umount"
410 type=$(blkid $fs | sed '/ TYPE=/!d;s/.* TYPE="\([^"]*\).*/\1/')
411 [ -n "$type" ] || continue
412 [ "$type" == "swap" ] && action="swapon"
413 if grep -q "^$fs " /proc/swaps; then
414 action="swapoff"
415 set -- $(grep "^$fs " /proc/swaps)
416 size=$(blk2h $(($3*2)))
417 used=$(blk2h $(($4*2)))
418 av=$(blk2h $((2*($3-$4))))
419 pct=$(((100*$4)/$3))%
420 mp=swap
421 fi
423 # size
424 [ -z "$size" ] &&
425 size="$(blk2h $(cat /sys/block/${fs#/dev/}/size /sys/block/*/${fs#/dev/}/size))"
427 # image
428 disktype="@hdd@"
429 case "$(cat /sys/block/${fs#/dev/}/removable 2>/dev/null ||
430 cat /sys/block/${fs:5:3}/removable 2>/dev/null)" in
431 1) disktype="@removable@" ;;
432 esac
433 case "$(cat /sys/block/${fs#/dev/}/ro 2>/dev/null ||
434 cat /sys/block/${fs:5:3}/ro 2>/dev/null)" in
435 1) disktype="@cd@" ;;
436 esac
438 radio="<input type=\"radio\" name=\"device\" value=\"$action $fs\" id=\"${fs#/dev/}\"/>"
439 [ "$REMOTE_USER" == "root" ] || radio=""
440 cat <<EOT
441 <tr>
442 <td>$radio<!--
443 --><label for="${fs#/dev/}" data-icon="$disktype">&thinsp;${fs#/dev/}</label></td>
444 <td>$(blkid $fs | sed '/LABEL=/!d;s/.*LABEL="\([^"]*\).*/\1/')</td>
445 <td>$type</td>
446 <td>$size</td>
447 <td>$av</td>
448 EOT
449 if [ -n "$pct" ]; then
450 cat <<EOT
451 <td class="meter"><meter min="0" max="100" value="${pct%%%}" low="70"
452 high="90" optimum="10"></meter>
453 <span>$used - $pct</span>
454 </td>
455 EOT
456 else
457 cat <<EOT
458 <td> </td>
459 EOT
460 fi
461 cat <<EOT
462 <td>$mp</td>
463 <td>$(blkid $fs | sed '/UUID=/!d;s/.*UUID="\([^"]*\).*/\1/')</td>
464 </tr>
465 EOT
466 done
467 cat <<EOT
468 </tbody>
469 </table>
470 EOT
471 [ "$REMOTE_USER" == "root" ] && cat <<EOT
472 $(lib crypto input)
474 <footer>
475 <button type="submit">mount / umount</button> -
476 $(_ 'new mount point:') <input type="text" name="mountpoint" value="/media/usbdisk"/> -
477 <input type="checkbox" name="readonly" id="ro"><label for="ro">&thinsp;$(_ 'read-only')</label>
478 </footer>
479 EOT
480 cat <<EOT
481 </form>
482 </section>
483 EOT
486 #
487 # /etc/fstab
488 #
489 cat <<EOT
490 <section>
491 <header>
492 $(_ 'Filesystems table')
493 $(edit_button /etc/fstab)
494 </header>
495 <table class="wide zebra center">
496 <thead>
497 <tr>
498 <td>$(_ 'Disk')</td>
499 <td>$(_ 'Mount point')</td>
500 <td>$(_ 'Type')</td>
501 <td>$(_ 'Options')</td>
502 <td>$(_ 'Freq')</td>
503 <td>$(_ 'Pass')</td>
504 </tr>
505 </thead>
506 <tbody>
507 EOT
509 grep -v '^#' /etc/fstab | awk '{
510 print "<tr><td>" $1 "</td><td>" $2 "</td><td>" $3 "</td><td>" $4
511 print "</td><td>" $5 "</td><td>" $6 "</td></tr>"
512 }
513 END{print "</tbody></table>"}'
515 cat <<EOT
516 </section>
517 EOT
520 #
521 # Loop device management GUI
522 #
523 cat <<EOT
524 <section>
525 <header>$(_ 'Loop devices')</header>
527 <form action="#loop" class="wide">
528 <div class="scroll">
529 <table id="loop" class="wide zebra scroll">
530 <thead>
531 <tr>
532 <td>$(_ 'Device')</td>
533 <td>$(_ 'Backing file')</td>
534 <td>$(_ 'Size')</td>
535 <td>$(_ 'Access')</td>
536 <td>$(_ 'Offset')</td>
537 </tr>
538 </thead>
539 <tbody>
540 EOT
541 for devloop in $(ls /dev/*loop[0-9]*); do
542 loop="${devloop#/dev/}"
543 dir=/sys/block/$loop
544 case "$(cat $dir/ro 2>/dev/null)" in
545 0) ro="$(_ "read/write")" ;;
546 1) ro="$(_ "read only")" ;;
547 *) ro="" ;;
548 esac
549 size=$(blk2h $(cat $dir/size))
550 [ "$size" == "0.0K" ] && size="" && ro=""
551 set -- $(losetup $devloop)
552 set -- "${3:-$(cat $dir/loop/backing_file)}" "${2:-$(cat $dir/loop/offset)}" ${ro// /&nbsp;}
553 cat <<EOT
554 <tr><td><input type="radio" name="loopdev" value="$devloop" id="$loop"/><!--
555 --><label for="$loop" data-icon="@loopback@">$loop</label></td>
556 <td>$1</td><td>$size</td><td align="center">$3</td><td align="right">$2</td>
557 </tr>
558 EOT
559 done
560 cat <<EOT
561 </tbody>
562 </table>
563 </div>
565 $(lib crypto input)
567 <footer>
568 <button type="submit" data-icon="@ok@">$(_ 'Setup')</button> -
569 $(_ 'new backing file:') <input type="text" name="backingfile"/> -
570 $(_ 'offset in bytes:') <input type="text" name="offset" value="0" size="8"/> -
571 <input type="checkbox" name="readonly" id="ro"/><label for="ro">$(_ 'read only')</label>
572 </footer>
573 </form>
574 </section>
575 EOT
578 #
579 # System memory
580 #
581 mem_total=$(free -m | awk '$1 ~ "M" {print $2}')
582 mem_used=$((100 * $(free -m | awk '$1 ~ "+" {print $3}') / mem_total))
583 mem_buff=$((100 * $(free -m | awk '$1 ~ "M" {print $6}') / mem_total))
584 mem_free=$((100 - mem_used - mem_buff))
586 cat <<EOT
587 <section>
588 <header>$(_ 'System memory')</header>
590 <div class="sysmem"><!--
591 --><span class="sysmem_used" style="width: ${mem_used}%" title="$(_ 'Used')" ><span>${mem_used}%</span></span><!--
592 EOT
593 [ $mem_buff != 0 ] && cat <<EOT
594 --><span class="sysmem_buff" style="width: ${mem_buff}%" title="$(_ 'Buffers')"><span>${mem_buff}%</span></span><!--
595 EOT
596 cat <<EOT
597 --><span class="sysmem_free" style="width: ${mem_free}%" title="$(_ 'Free')" ><span>${mem_free}%</span></span><!--
598 --></div>
600 <table class="wide zebra center">
601 <thead>
602 <tr>
603 <td>&nbsp;</td>
604 <td>total</td>
605 <td>used</td>
606 <td>free</td>
607 <td>shared</td>
608 <td>buffers</td>
609 </tr>
610 </thead>
611 <tbody>
612 EOT
614 free -m | awk '
615 $1 ~ "M" {print "<tr><td>"$1"</td><td>"$2"</td><td>"$3"</td><td>"$4"</td><td>"$5"</td><td>"$6"</td></tr>"}
616 $1 ~ "+" {print "<tr><td>"$1 $2"</td><td></td><td>"$3"</td><td>"$4"</td><td></td><td></td></tr>"}
617 $1 ~ "S" {print "<tr><td>"$1"</td><td>"$2"</td><td>"$3"</td><td>"$4"</td><td></td><td></td></tr>"}'
619 cat <<EOT
620 </tbody>
621 </table>
622 </section>
623 EOT
626 #
627 # lspci and lsusb summary tables
628 #
629 cat <<EOT
630 <section>
631 <header>lspci</header>
632 $(lspci_table)
633 </section>
636 <section>
637 <header>lsusb</header>
638 $(lsusb_table)
639 </section>
640 EOT
641 ;;
642 esac
644 xhtml_footer
645 exit 0