tazpanel view hardware.cgi @ rev 434

boot.cgi: user support
author Pascal Bellard <pascal.bellard@slitaz.org>
date Mon Apr 06 20:48:48 2015 +0200 (2015-04-06)
parents 73305834575f
children fa8dd339b418
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=$(gettext '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_table() {
31 cat <<EOT
32 <table class="wide zebra">
33 <thead>
34 <tr>
35 <td>$(gettext 'Bus')</td>
36 <td>$(gettext 'Device')</td>
37 <td>$(gettext 'ID')</td>
38 <td>$(gettext 'Name')</td>
39 </tr>
40 </thead>
41 <tbody>
42 EOT
43 lsusb | sed 's|^Bus \([0-9]*\)|<tr><td>\1</td>|;
44 s|</td> Device \([0-9]*\):|</td><td>\1</td>|;
45 s|</td> ID \([^:]*:[^ ]*\)|</td><td><a href="?lsusb=\1">\1</a></td>|;
46 s| |<td>|2;
47 s|.*$|\0</td></tr>|'
48 echo "</tbody></table>"
49 }
52 lspci_table() {
53 cat <<EOT
54 <table class="wide zebra">
55 <thead><tr><td>Slot</td><td>Device</td><td>Name</td></thead>
56 <tbody>
57 EOT
58 lspci | sed 's| |</td><td>|;
59 s|: |</td><td>|;
60 s|^\([^<]*\)|<a href="?lspci=\1">\1</a>|;
61 s|^.*$|<tr><td>\0</td></tr>|'
62 echo "</tbody></table>"
63 }
66 #
67 # Commands
68 #
70 case " $(GET) " in
71 *\ print\ *)
72 xhtml_header
73 echo "<h2>TODO</h2>"
74 ;;
77 *\ tazx\ *)
78 xhtml_header
79 cat <<EOT
80 <pre>$(tazx auto)</pre>
81 EOT
82 ;;
85 *\ detect\ *)
86 # Front end for Tazhw
87 # TODO: Add button to detect webcam, etc. Like in tazhw box.
88 xhtml_header
89 cat <<EOT
90 <h2>$(gettext 'Detect hardware')</h2>
91 <p>$(gettext 'Detect PCI and USB hardware')</p>
93 <section>
94 <pre>$(tazhw detect-pci | sed 's|^>|\&gt;|g')</pre>
95 <pre>$(tazhw detect-usb | sed 's|^>|\&gt;|g')</pre>
96 </section>
97 EOT
98 ;;
101 *\ modules\ *|*\ modinfo\ *)
102 xhtml_header
103 cat <<EOT
104 <h2>$(gettext 'Kernel modules')</h2>
106 <form id="actions">
107 <input type="hidden" name="modules"/>
108 $(gettext 'Manage, search or get information about the Linux kernel modules')
110 <input type="search" name="search" class="float-right" placeholder="$(gettext 'Modules search')" results="5" autosave="modsearch" autocomplete="on"/>
111 </form>
112 EOT
113 # Request may be modinfo output that we want in the page itself
114 get_modinfo="$(GET modinfo)"
115 if [ -n "$get_modinfo" ]; then
116 cat <<EOT
117 <section>
118 <header>$(eval_gettext 'Detailed information for module: $get_modinfo')</header>
120 EOT
121 modinfo $get_modinfo | awk 'BEGIN{print "<table class=\"wide zebra\">"}
122 {
123 printf("<tr><td><b>%s</b></td>", $1)
124 $1=""; printf("<td>%s</td></tr>", $0)
125 }
126 END{print "</table></section>"}'
127 fi
129 if [ -n "$(GET modprobe)" ]; then
130 echo "<pre>$(modprobe -v $(GET modprobe))</pre>"
131 fi
132 if [ -n "$(GET rmmod)" ]; then
133 echo "Removing"
134 rmmod -w $(GET rmmod)
135 fi
136 get_search="$(GET search)"
137 if [ -n "$get_search" ]; then
138 eval_gettext 'Matching result(s) for: $get_search'
139 echo '<pre>'
140 modprobe -l | grep "$(GET search)" | while read line
141 do
142 name=$(basename $line)
143 mod=${name%.ko.gz}
144 echo "$(gettext 'Module:') <a href='?modinfo=$mod'>$mod</a>"
145 done
146 echo '</pre>'
147 fi
148 cat <<EOT
149 <section>
150 <table class="zebra">
151 <thead>
152 <tr>
153 <td>$(gettext 'Module')</td>
154 <td>$(gettext 'Description')</td>
155 <td>$(gettext 'Size')</td>
156 <td>$(gettext 'Used')</td>
157 <td>$(gettext 'by')</td>
158 </tr>
159 <thead>
160 <tbody>
161 EOT
162 # Get the list of modules and link to modinfo
163 lsmod | tail -n+2 | awk '{
164 gsub(",", " ", $4);
165 printf("<tr><td><a href=\"?modinfo=%s\">%s</a></td><td>", $1, $1);
166 system("modinfo -d " $1);
167 printf("</td><td>%s</td><td>%s</td><td>%s</td></tr>", $2, $3, $4);
168 }'
169 cat <<EOT
170 </thead>
171 </table>
172 </section>
173 EOT
174 ;;
177 *\ lsusb\ *)
178 xhtml_header
179 vidpid="$(GET lsusb)"
180 cat <<EOT
181 <h2>$(eval_gettext 'Information for USB Device $vidpid')</h2>
183 <p>$(gettext 'Detailed information about specified device.')</p>
185 <section>$(lsusb_table)</section>
186 EOT
187 [ "$vidpid" != 'lsusb' ] && cat <<EOT
188 <section>
189 <pre style="white-space: pre-wrap">$(lsusb -vd $vidpid | syntax_highlighter lsusb)</pre>
190 </section>
191 EOT
192 ;;
195 *\ lspci\ *)
196 xhtml_header
197 slot="$(GET lspci)"
198 cat <<EOT
199 <h2>$(eval_gettext 'Information for PCI Device $slot')</h2>
201 <p>$(gettext 'Detailed information about specified device.')</p>
203 <section>$(lspci_table)</section>
204 EOT
205 [ "$slot" != 'lspci' ] && cat <<EOT
206 <section>
207 <pre style="white-space: pre-wrap">$(lspci -vs $slot | syntax_highlighter lspci)</pre>
208 </section>
209 EOT
210 ;;
213 *)
214 [ -n "$(GET brightness)" ] &&
215 echo -n $(GET brightness) > /sys/devices/virtual/backlight/$(GET dev)/brightness
217 #
218 # Default to summary with mounted filesystem, loaded modules
219 #
220 xhtml_header
221 cat <<EOT
222 <h2>$(gettext 'Drivers &amp; Devices')</h2>
223 <p>$(gettext 'Manage your computer hardware')</p>
225 <form><!--
226 EOT
227 [ "$REMOTE_USER" == "root" ] && cat <<EOT
228 --><button name="detect" data-icon="detect" >$(gettext 'Detect PCI/USB')</button><!--
229 --><button name="tazx" data-icon="tazx" >$(gettext 'Auto-install Xorg video driver')</button><!--
230 EOT
231 cat <<EOT
232 --><button name="modules" data-icon="modules">$(gettext 'Kernel modules')</button>
233 </form>
235 EOT
238 # Battery state
239 if [ -n "$(ls /proc/acpi/battery/*/info 2>/dev/null)" ]; then
240 cat <<EOT
241 <section>
242 <header>$(gettext 'Battery')</header>
243 <div>
244 <table class="wide">
245 EOT
246 for dev in /proc/acpi/battery/*; do
247 grep ^present $dev/info | grep -q yes || continue
248 design=$(sed '/design capacity:/!d; s/[^0-9]*\([0-9]*\).*/\1/' < $dev/info)
249 remain=$(sed '/remaining capacity/!d; s/[^0-9]*\([0-9]*\).*/\1/' < $dev/state)
250 rate=$(sed '/present rate/!d; s/[^0-9]*\([0-9]*\).*/\1/' < $dev/state)
251 full=$(sed '/last full capacity/!d; s/[^0-9]*\([0-9]*\).*/\1/' < $dev/info)
252 warning=$(sed '/design capacity warning/!d;s/[^0-9]*\([0-9]*\).*/\1/' < $dev/info)
253 low=$(sed '/design capacity low/!d; s/[^0-9]*\([0-9]*\).*/\1/' < $dev/info)
254 state=$(sed '/charging state/!d; s/\([^:]*:[ ]\+\)\([a-z]\+\)/\2/' < $dev/state)
256 rempct=$(( $remain * 100 / $full ))
257 cat <<EOT
258 <tr>
259 <td><span data-icon="battery">$(gettext 'Battery')</span>
260 $(grep "^battery type" $dev/info | sed 's/.*: *//')
261 $(grep "^design capacity:" $dev/info | sed 's/.*: *//') </td>
262 <td>$(gettext 'health') $(( (100*$full)/$design))%</td>
263 <td class="meter"><meter min="0" max="$full" value="$remain" low="$low"
264 high="$warning" optimum="$full"></meter>
265 <span>
266 EOT
267 case "$state" in
268 "discharging")
269 remtime=$(( $remain * 60 / $rate ))
270 remtimef=$(printf "%d:%02d" $(($remtime/60)) $(($remtime%60)))
271 eval_gettext 'Discharging $rempct% - $remtimef' ;;
272 "charging")
273 remtime=$(( ($full - $remain) * 60 / $rate ))
274 remtimef=$(printf "%d:%02d" $(($remtime/60)) $(($remtime%60)))
275 eval_gettext 'Charging $rempct% - $remtimef' ;;
276 "charged")
277 gettext 'Charged 100%' ;;
278 esac
279 cat <<EOT
281 </span>
282 </td>
283 </tr>
284 EOT
285 done
286 cat <<EOT
287 </table>
288 </div>
289 </section>
290 EOT
291 fi
294 # Thermal sensors
295 if [ -n "$(ls /sys/devices/virtual/thermal/*/temp 2>/dev/null)" ]; then
296 echo "<p><span data-icon=\"temperature\">$(gettext 'Temperature:')</span>"
297 for temp in /sys/devices/virtual/thermal/*/temp; do
298 awk '{ print $1/1000 "℃" }' < $temp
299 done
300 echo '</p>'
301 fi
304 # Brightness
305 if [ -n "$(ls /sys/devices/virtual/backlight/*/brightness 2>/dev/null)" ]; then
306 echo '<form>'
307 for dev in /sys/devices/virtual/backlight/*/brightness; do
308 name=$(echo $dev | sed 's|.*/backlight/\([^/]*\).*|\1|')
309 cat <<EOT
310 <input type="hidden" name="dev" value="$name"/>
311 <span data-icon="brightness">$(gettext 'Brightness')</span> \
312 $(sed 's/.*\.//;s/_*$//' < /sys/devices/virtual/backlight/$name/device/path):
313 <select name="brightness" onchange="submit();">
314 EOT
315 max=$(cat /sys/devices/virtual/backlight/$name/max_brightness)
316 for i in $(seq 0 $max); do
317 echo -n "<option value=\"$i\""
318 [ $i -eq $(cat /sys/devices/virtual/backlight/$name/actual_brightness) ] &&
319 echo -n " selected=\"selected\""
320 echo "> $(( (($i + 1) * 100) / ($max + 1) ))% </option>"
321 done
322 echo '</select>'
323 done
324 echo '</form>'
325 fi
328 cat <<EOT
329 <section>
330 <form action="#mount" class="wide">
331 <header id="disk">$(gettext 'Filesystem usage statistics')</header>
332 <div>
333 <pre>$(disk_info)</pre>
334 </div>
335 EOT
338 #
339 # Loop device management actions
340 #
341 device=$(GET loopdev)
342 lib crypto $device
343 case "$device" in
344 /dev/*loop*)
345 set -- $(losetup | grep ^$device:)
346 [ -n "$3" ] && losetup -d $device
347 ro=""
348 [ -n "$(GET readonly)" ] && ro="-r"
349 file="$(GET backingfile)"
350 [ -n "$file" ] && losetup -o $(GET offset) $ro $device $file
351 esac
354 #
355 # Disk stats and management (mount, umount, check)
356 #
357 device=$(GET device)
358 lib crypto $device
359 case "$device" in
360 *[\;\`\&\|\$]*) ;;
361 mount\ *)
362 ro=""
363 [ -n "$(GET readonly)" ] && ro="-r"
364 mntdir="$(GET mountpoint)"
365 [ -d "$mntdir" ] || mkdir -p "$mntdir"
366 $device $ro "$mntdir";;
367 umount\ *|swapon\ *|swapoff\ *)
368 $device ;;
369 esac
370 cat <<EOT
371 <table id="mount" class="zebra wide center">
372 EOT
373 df_thead
374 echo '<tbody>'
375 for fs in $(blkid | sort | sed 's/:.*//'); do
376 set -- $(df -h | grep "^$fs ")
377 size=$2
378 used=$3
379 av=$4
380 grep "^$fs " /proc/mounts | grep -q "[, ]ro[, ]" &&
381 av="<del>$av</del>"
382 pct=$5
383 mp=$6
385 # action
386 action="mount"
387 [ -n "$mp" ] && action="umount"
388 type=$(blkid $fs | sed '/TYPE=/!d;s/.* TYPE="\([^"]*\).*/\1/')
389 [ "$type" == "swap" ] && action="swapon"
390 if grep -q "^$fs " /proc/swaps; then
391 action="swapoff"
392 set -- $(grep "^$fs " /proc/swaps)
393 size=$(blk2h $(($3*2)))
394 used=$(blk2h $(($4*2)))
395 av=$(blk2h $((2*($3-$4))))
396 pct=$(((100*$4)/$3))%
397 mp=swap
398 fi
400 # size
401 [ -z "$size" ] &&
402 size="$(blk2h $(cat /sys/block/${fs#/dev/}/size /sys/block/*/${fs#/dev/}/size))"
404 # image
405 disktype="hdd"
406 case "$(cat /sys/block/${fs#/dev/}/removable 2>/dev/null ||
407 cat /sys/block/${fs:5:3}/removable 2>/dev/null)" in
408 1) disktype="removable" ;;
409 esac
410 case "$(cat /sys/block/${fs#/dev/}/ro 2>/dev/null ||
411 cat /sys/block/${fs:5:3}/ro 2>/dev/null)" in
412 1) disktype="cd" ;;
413 esac
415 cat <<EOT
416 <tr>
417 <td><input type="radio" name="device" value="$action $fs" id="${fs#/dev/}"/><!--
418 --><label for="${fs#/dev/}" data-icon="$disktype">&thinsp;${fs#/dev/}</label></td>
419 <td>$(blkid $fs | sed '/LABEL=/!d;s/.*LABEL="\([^"]*\).*/\1/')</td>
420 <td>$type</td>
421 <td>$size</td>
422 <td>$av</td>
423 EOT
424 if [ -n "$pct" ]; then
425 cat <<EOT
426 <td class="meter"><meter min="0" max="100" value="${pct%%%}" low="70"
427 high="90" optimum="10"></meter>
428 <span>$used - $pct</span>
429 </td>
430 EOT
431 else
432 cat <<EOT
433 <td> </td>
434 EOT
435 fi
436 cat <<EOT
437 <td>$mp</td>
438 <td>$(blkid $fs | sed '/UUID=/!d;s/.*UUID="\([^"]*\).*/\1/')</td>
439 </tr>
440 EOT
441 done
442 cat <<EOT
443 </tbody>
444 </table>
445 EOT
446 [ "$REMOTE_USER" == "root" ] && cat <<EOT
447 $(lib crypto input)
449 <footer>
450 <button type="submit">mount / umount</button> -
451 $(gettext 'new mount point:') <input type="text" name="mountpoint" value="/media/usbdisk"/> -
452 <input type="checkbox" name="readonly" id="ro"><label for="ro">&thinsp;$(gettext 'read-only')</label>
453 </footer>
454 EOT
455 cat <<EOT
456 </form>
457 </section>
458 EOT
461 #
462 # /etc/fstab
463 #
464 cat <<EOT
465 <section>
466 <header>
467 $(gettext 'Filesystems table')
468 <form action="index.cgi">
469 <input type="hidden" name="file" value="/etc/fstab"/>
470 <button name="action" value="edit" data-icon="edit">$(gettext 'Edit')</button>
471 </form>
472 </header>
473 <table class="wide zebra center">
474 <thead>
475 <tr>
476 <td>$(gettext 'Disk')</td>
477 <td>$(gettext 'Mount point')</td>
478 <td>$(gettext 'Type')</td>
479 <td>$(gettext 'Options')</td>
480 <td>$(gettext 'Freq')</td>
481 <td>$(gettext 'Pass')</td>
482 </tr>
483 </thead>
484 <tbody>
485 EOT
487 grep -v '^#' /etc/fstab | awk '{
488 print "<tr><td>" $1 "</td><td>" $2 "</td><td>" $3 "</td><td>" $4
489 print "</td><td>" $5 "</td><td>" $6 "</td></tr>"
490 }
491 END{print "</tbody></table>"}'
493 cat <<EOT
494 </section>
495 EOT
498 #
499 # Loop device management GUI
500 #
501 cat <<EOT
502 <section>
503 <header>$(gettext 'Loop devices')</header>
505 <form action="#loop" class="wide">
506 <div class="scroll">
507 <table id="loop" class="wide zebra scroll">
508 <thead>
509 <tr>
510 <td>$(gettext 'Device')</td>
511 <td>$(gettext 'Backing file')</td>
512 <td>$(gettext 'Access')</td>
513 <td>$(gettext 'Offset')</td>
514 </tr>
515 </thead>
516 <tbody>
517 EOT
518 for devloop in $(ls /dev/*loop[0-9]*); do
519 loop="${devloop#/dev/}"
520 case "$(cat /sys/block/$loop/ro 2>/dev/null)" in
521 0) ro="$(gettext "read/write")" ;;
522 1) ro="$(gettext "read only")" ;;
523 *) ro="" ;;
524 esac
525 set -- $(losetup | grep ^$devloop:) ${ro// /&nbsp;}
526 cat <<EOT
527 <tr><td><input type="radio" name="loopdev" value="$devloop" id="$loop"/><!--
528 --><label for="$loop" data-icon="loopback">$loop</label></td>
529 <td>$3</td><td align="center">$4</td><td align="right">$2</td>
530 </tr>
531 EOT
532 done
533 cat <<EOT
534 </tbody>
535 </table>
536 </div>
538 $(lib crypto input)
540 <footer>
541 <button type="submit" data-icon="ok">$(gettext 'Setup')</button> -
542 $(gettext 'new backing file:') <input type="text" name="backingfile"/> -
543 $(gettext 'offset in bytes:') <input type="text" name="offset" value="0" size="8"/> -
544 <input type="checkbox" name="readonly" id="ro"/><label for="ro">$(gettext 'read only')</label>
545 </footer>
546 </form>
547 </section>
548 EOT
551 #
552 # System memory
553 #
554 mem_total=$(free -m | awk '$1 ~ "M" {print $2}')
555 mem_used=$((100 * $(free -m | awk '$1 ~ "+" {print $3}') / mem_total))
556 mem_buff=$((100 * $(free -m | awk '$1 ~ "M" {print $6}') / mem_total))
557 mem_free=$((100 - mem_used - mem_buff))
559 cat <<EOT
560 <section>
561 <header>$(gettext 'System memory')</header>
563 <div class="sysmem"><!--
564 --><span class="sysmem_used" style="width: ${mem_used}%" title="$(gettext 'Used')" ><span>${mem_used}%</span></span><!--
565 EOT
566 [ $mem_buff != 0 ] && cat <<EOT
567 --><span class="sysmem_buff" style="width: ${mem_buff}%" title="$(gettext 'Buffers')"><span>${mem_buff}%</span></span><!--
568 EOT
569 cat <<EOT
570 --><span class="sysmem_free" style="width: ${mem_free}%" title="$(gettext 'Free')" ><span>${mem_free}%</span></span><!--
571 --></div>
573 <table class="wide zebra center">
574 <thead>
575 <tr>
576 <td>&nbsp;</td>
577 <td>total</td>
578 <td>used</td>
579 <td>free</td>
580 <td>shared</td>
581 <td>buffers</td>
582 </tr>
583 </thead>
584 <tbody>
585 EOT
587 free -m | awk '
588 $1 ~ "M" {print "<tr><td>"$1"</td><td>"$2"</td><td>"$3"</td><td>"$4"</td><td>"$5"</td><td>"$6"</td></tr>"}
589 $1 ~ "+" {print "<tr><td>"$1 $2"</td><td></td><td>"$3"</td><td>"$4"</td><td></td><td></td></tr>"}
590 $1 ~ "S" {print "<tr><td>"$1"</td><td>"$2"</td><td>"$3"</td><td>"$4"</td><td></td><td></td></tr>"}'
592 cat <<EOT
593 </tbody>
594 </table>
595 </section>
596 EOT
599 #
600 # lspci and lsusb summary tables
601 #
602 cat <<EOT
603 <section>
604 <header>lspci</header>
605 $(lspci_table)
606 </section>
609 <section>
610 <header>lsusb</header>
611 $(lsusb_table)
612 </section>
613 EOT
614 ;;
615 esac
617 xhtml_footer
618 exit 0