tazpanel view hardware.cgi @ rev 523

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