tazpanel view hardware.cgi @ rev 419

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