tazpanel view hardware.cgi @ rev 499

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