Продолжим небольшое программное исследование Wi-Fi-роутера TP-LINK TL-MR3020 под управлением OR-WRT (редакция OpenWrt от робофорума).
Сначала посмотрим те конфигурационные файлы, которые я забыл показать в прошлой статье-исследовании.
login as: root [email protected]'s password: BusyBox v1.19.4 (2012-08-21 01:06:25 UTC) built-in shell (ash) Enter 'help' for a list of built-in commands. _______ ________ __ | |.-----.-----.-----.| | | |.----.| |_ | - || _ | -__| || | | || _|| _| |_______|| __|_____|__|__||________||__| |____| |__| W I R E L E S S F R E E D O M ---------------------------------------------------------------------- ____ ____ __ __ _ / __ \____ ___ ____ / __ \____ / /_ ____ / /_(_)__________ / / / / __ \/ _ \/ __ \____/ /_/ / __ \/ __ \/ __ \/ __/ // ___/ ___/ / /_/ / /_/ / __/ / / /___/ _, _/ /_/ / /_/ / /_/ / /_/ // /__(__ ) \____/ .___/\___/_/ /_/ /_/ |_|\____/_.___/\____/\__/_/ \___/____/ /_/ root@OpenWrt:~# # cat /etc/banner _______ ________ __ | |.-----.-----.-----.| | | |.----.| |_ | - || _ | -__| || | | || _|| _| |_______|| __|_____|__|__||________||__| |____| |__| W I R E L E S S F R E E D O M ---------------------------------------------------------------------- ____ ____ __ __ _ / __ \____ ___ ____ / __ \____ / /_ ____ / /_(_)__________ / / / / __ \/ _ \/ __ \____/ /_/ / __ \/ __ \/ __ \/ __/ // ___/ ___/ / /_/ / /_/ / __/ / / /___/ _, _/ /_/ / /_/ / /_/ / /_/ // /__(__ ) \____/ .___/\___/_/ /_/ /_/ |_|\____/_.___/\____/\__/_/ \___/____/ /_/
~# cat /etc/ser2net.conf # # This is an example configuration file for ser2net. It has the following # format: # :::: # TCP port # Name or number of the TCP/IP port to accept con- # nections from for this device. A port number may # be of the form [host,]port, such as 127.0.0.1,2000 # or localhost,2000. If this is specified, it will # only bind to the IP address specified. Otherwise # it will bind to all the ports on the machine. # # state Either raw or rawlp or telnet or off. off disables # the port from accepting connections. It can be # turned on later from the control port. raw enables # the port and transfers all data as-is between the # port and the long. rawlp enables the port and # transfers all input data to device, device is open # without any termios setting. It allow to use # /dev/lpX devices and printers connected to them. # telnet enables the port and runs the telnet proto- # col on the port to set up telnet parameters. This # is most useful for using telnet. # # timeout # The time (in seconds) before the port will be dis- # connected if there is no activity on it. A zero # value disables this function. # # device The name of the device to connect to. This # must be in the form of /dev/. # # options # Sets operational parameters for the serial port. # Options 300, 1200, 2400, 4800, 9600, 19200, 38400, # 57600, 115200 set the various baud rates. EVEN, # ODD, NONE set the parity. 1STOPBIT, 2STOPBITS set # the number of stop bits. 7DATABITS, 8DATABITS set # the number of data bits. [-]XONXOFF turns on (- # off) XON/XOFF support. [-]RTSCTS turns on (- off) # hardware flow control, [-]LOCAL turns off (- on) # monitoring of the modem lines, and # [-]HANGUP_WHEN_DONE turns on (- off) lowering the # modem control lines when the connection is done. # NOBREAK disables automatic setting of the break # setting of the serial port. # The "remctl" option allow remote control (ala RFC # 2217) of serial-port configuration. A banner name # may also be specified, that banner will be printed # for the line. If no banner is given, then no # banner is printed. # The tw, tr, and tb options take a tracefile name ( # specified in TRACEFILE that will take all traced data. # tw is data written to the device, tr is data read from # the device, and tb is both. # # or... # BANNER::banner # This will create a banner, if the banner name is given in the # options of a line, that banner will be printed. This takes the # standard "C" \x characters (\r is carraige return, \n is newline, # etc.). It also accepts \d, which prints the device name, \p, # which prints the TCP port number, and \s which prints the serial # parameters (eg 9600N81). Banners can span lines if the last # character on a line is '\'. Note that you *must* use \r\n to # start a new line. # # TRACEFILE::filename # This specifies a filename to trace output into, as tw:/tmp/trace1. # This takes a large number of escape sequences, see the man page # for details on these options. # # Note that the same device can be listed multiple times under different # ports, this allows the same serial port to have both telnet and raw # protocols. BANNER:banner1:Welcome to ser2net TCP port \p device \d\r\n\ second line \ third line\r\n BANNER:banner2:this is ser2net TCP port \p device \d\r\n\ second line \ third line\r\n BANNER:banner3:this is ser2net TCP port \p device \d serial parms \s\r\n TRACEFILE:tw1:/tmp/tw-\p-\Y-\M-\D-\H:\i:\s.\U TRACEFILE:tr1:/tmp/tr-\p-\Y-\M-\D-\H:\i:\s.\U 2000:raw:600:/dev/ttyATH0:115200 NONE 1STOPBIT 8DATABITS -XONXOFF -LOCAL -RTSCTS 3000:raw:600:/dev/ttyUSB0:115200 NONE 1STOPBIT 8DATABITS -XONXOFF -LOCAL -RTSCTS 3001:raw:600:/dev/ttyUSB1:115200 NONE 1STOPBIT 8DATABITS -XONXOFF -LOCAL -RTSCTS 3002:raw:600:/dev/ttyUSB2:115200 NONE 1STOPBIT 8DATABITS -XONXOFF -LOCAL -RTSCTS 3003:raw:600:/dev/ttyUSB3:115200 NONE 1STOPBIT 8DATABITS -XONXOFF -LOCAL -RTSCTS 3004:raw:600:/dev/ttyUSB4:115200 NONE 1STOPBIT 8DATABITS -XONXOFF -LOCAL -RTSCTS 3005:raw:600:/dev/ttyUSB5:115200 NONE 1STOPBIT 8DATABITS -XONXOFF -LOCAL -RTSCTS #2002:raw:600:/dev/ttyS1:9600 NONE 1STOPBIT 8DATABITS XONXOFF LOCAL -RTSCTS #2003:raw:5:/dev/ttyS2:9600 #2004:raw:5:/dev/ttyS3:115200 #2005:raw:5:/dev/ttyS4:9600 #2006:raw:5:/dev/ttyS5:9600 #2007:raw:5:/dev/ttyS6:9600 tw=tw1 tr=tr1 #3001:telnet:0:/dev/ttyS0:19200 remctl banner1 #3011:telnet:3:/dev/ttyS0:19200 banner2 #3002:telnet:0:/dev/ttyS1:9600 #3003:telnet:0:/dev/ttyS2:9600 banner3 #3004:telnet:0:/dev/ttyS3:115200 #3005:telnet:0:/dev/ttyS4:9600 #3006:telnet:0:/dev/ttyS5:9600 #3007:telnet:0:/dev/ttyS6:9600 #5001:rawlp:10:/dev/lp0
# netstat -ant Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:2000 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:53 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:88 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:3000 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:3001 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:3002 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:3003 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:3004 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:3005 0.0.0.0:* LISTEN tcp 0 100 192.168.217.1:22 192.168.217.15:1324 ESTABLISHED netstat: /proc/net/tcp6: No such file or directory
# mount rootfs on / type rootfs (rw) /dev/root on /rom type squashfs (ro,relatime) proc on /proc type proc (rw,noatime) sysfs on /sys type sysfs (rw,noatime) tmpfs on /tmp type tmpfs (rw,nosuid,nodev,noatime) tmpfs on /dev type tmpfs (rw,noatime,size=512k,mode=755) devpts on /dev/pts type devpts (rw,noatime,mode=600) /dev/mtdblock3 on /overlay type jffs2 (rw,noatime) overlayfs:/overlay on / type overlayfs (rw,relatime,lowerdir=/,upperdir=/overlay) debugfs on /sys/kernel/debug type debugfs (rw,relatime) none on /proc/bus/usb type usbfs (rw,relatime)
Смотрим содержимое нашей веб-морды 🙂
# ls -asl /www/ 0 drwxr-xr-x 1 root root 0 Jan 1 00:15 . 0 drwxr-xr-x 1 root root 0 Jan 1 00:00 .. 0 drwxr-xr-x 2 root root 112 May 27 2012 admin 0 drwxr-xr-x 1 root root 0 Jan 1 00:29 cgi-bin 5 -rw-r--r-- 1 root root 4946 Jan 1 1970 index.html 1 -rw-r--r-- 1 root root 1352 Jan 1 00:04 mylua.html 0 -rw-r--r-- 1 root root 15 Jan 1 1970 nothing.html 0 drwxr-xr-x 2 root root 31 Nov 26 2011 res 0 drwxr-xr-x 2 root root 763 Sep 1 2012 webcam # ls -asl /www/cgi-bin/ 0 drwxr-xr-x 1 root root 0 Jan 1 00:29 . 0 drwxr-xr-x 1 root root 0 Jan 1 00:15 .. 0 drwxr-xr-x 2 root root 132 Aug 30 2012 admin 1 -rwxr-xr-x 1 root root 1284 Jan 1 00:23 mylua.cgi 0 -rwxr-xr-x 1 root root 202 Nov 26 2011 restart_webcam.cgi 0 -rwxr-xr-x 1 root root 367 May 27 2012 serial.cgi 0 -rwxr-xr-x 1 root root 251 Jan 1 1970 uptime
# cat /www/index.html <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>OR-WIFI-ROBOT</title> <link rel="stylesheet" type="text/css" href="res/main.css"/> <script type="text/javascript"> var lastTurn = -1; var lastPress = -1; var lastPos = -1; function submitUART(uartString) { document.getElementById('serialData').value=uartString+"\n"; document.getElementById('serialForm').submit() }; function scrollCam(val) { document.getElementById("scr").parentNode.scrollLeft=val; }; function keyPressed(e) { var keynum var keychar var numcheck if(window.event) // IE { keynum = e.keyCode } else if(e.which) // Netscape/Firefox/Opera { keynum = e.which } keychar = String.fromCharCode(keynum); if(keychar == "w" || keychar == "Ж" || keychar == "W" || keychar == "ж") submitUART("DrvLR=100,100"); if(keychar == "a" || keychar == "Т" || keychar == "A" || keychar == "т") submitUART("DrvLR=-100,100"); if(keychar == "s" || keychar == "Ш" || keychar == "S" || keychar == "ш") submitUART("DrvLR=-100,-100"); if(keychar == "d" || keychar == "Б" || keychar == "D" || keychar == "б") submitUART("DrvLR=100,-100"); return true; }; function keyUp(e) { var keynum var keychar var numcheck if(window.event) // IE { keynum = e.keyCode } else if(e.which) // Netscape/Firefox/Opera { keynum = e.which } keychar = String.fromCharCode(keynum); if(keychar == "w" || keychar == "Ж" || keychar == "W" || keychar == "ж") submitUART("DrvLR=0,0"); if(keychar == "a" || keychar == "Т" || keychar == "A" || keychar == "т") submitUART("DrvLR=0,0"); if(keychar == "s" || keychar == "Ш" || keychar == "S" || keychar == "ш") submitUART("DrvLR=0,0"); if(keychar == "d" || keychar == "Б" || keychar == "D" || keychar == "б") submitUART("DrvLR=0,0"); return true; }; window.setInterval( function(){ var pos = document.getElementById("scr").parentNode.scrollLeft; if(lastPos!=pos){ submitUART("#9 P" +(pos + 700)); lastPos=pos; }; },100 ); </script> </head> <body onKeyPress="return keyPressed(event)" onKeyUp="keyUp(event)"> <pre class="banner"> ******************************************************************************************** * ____ ____ __ __ _ * * / __ \____ ___ ____ / __ \____ / /_ ____ / /_(_)__________ _______ __ * * / / / / __ \/ _ \/ __ \______/ /_/ / __ \/ __ \/ __ \/ __/ // ___/ ___/ / ___/ / / / * * / /_/ / /_/ / __/ / / /_____/ _, _/ /_/ / /_/ / /_/ / /_/ // /__(__ )_ / / / /_/ / * * \____/ .___/\___/_/ /_/ /_/ |_|\____/_.___/\____/\__/_/ \___/____/(_)_/ \__,_/ * * /_/ * * <b>Made by <a href="http://open-robotics.ru/" target="_blank">Open-Robotics.ru</a></b> Powered by <a href="http://openwrt.org" target="_blank">OpenWrt.org</a> * ******************************************************************************************** </pre> <table> <tr> <td> <script type="text/javascript"> document.write("<img alt='Robot Eye' class='bot-eye' src='http://" + document.location.host + ":8080/?action=stream'/>") </script> Camera control: <button type="button" onclick="scrollCam(0)">Left</button> <button type="button" onclick="scrollCam(800)">Center</button> <button type="button" onclick="scrollCam(1600)">Right</button> <div style="width:320px;height: 20px;margin-top: 15px;overflow-x: scroll;display: inline-block;" onscroll="scrollCam(this.scrollLeft)"> <div id="scr" style="width:1920px;height: 1px;display: block;" ></div> </div> </td> </tr> <tr> <td> <hr style="width: 240px;margin-top: 15px"> Chassis control: W-Forward, A-Left, S-Backward, D-Right </td> </tr> <tr> <td> <hr style="width: 240px;margin-top: 15px"> <form id="serialForm" action="/cgi-bin/serial.cgi" method="POST" target="hidden"> <label>Serial data: <textarea id="serialData" name="SERIAL_DATA" rows="2" cols="40">TEST SERIAL</textarea> </label> <input type="submit" value="Send"> </form> </td> </tr> </table> <hr/> <iframe name="hidden" src="/nothing.html" style="width: 1px;height: 1px;visibility: hidden"></iframe> <a href="admin/index.html">Robot administration</a> </body> </html>
# cat /www/cgi-bin/serial.cgi #!/usr/bin/awk -f function unescape(s) { gsub(/\+/," ",s) res = "" do { p = match(s,/%[0-9a-fA-F]{2}/) if(p>0) { res = res substr(s,0,p-1) sprintf("%c",0+("0x" substr(s,p+1,2))) s = substr(s,p+3) } } while(p>0) return res s } BEGIN { RS = "&" FS = "=" } { if($1 == "SERIAL_DATA" ) print unescape($2) > "/dev/ttyUSB0" } END { print "202" }
админка:
# ls -asl /www/admin/ 0 drwxr-xr-x 2 root root 112 May 27 2012 . 0 drwxr-xr-x 1 root root 0 Jan 1 00:15 .. 4 -rw-r--r-- 1 root root 3730 May 27 2012 camshow.html 2 -rw-r--r-- 1 root root 2178 Jan 1 1970 index.html 2 -rw-r--r-- 1 root root 2203 Jan 1 1970 passwd.html 3 -rw-r--r-- 1 root root 2890 Jan 1 1970 uhttpd.html 4 -rw-r--r-- 1 root root 3937 Jan 1 1970 wifishow.html # ls -asl /www/res/ 0 drwxr-xr-x 2 root root 31 Nov 26 2011 . 0 drwxr-xr-x 1 root root 0 Jan 1 00:15 .. 1 -rw-r--r-- 1 root root 554 Jan 1 00:47 main.css # ls -asl /www/webcam/ 0 drwxr-xr-x 2 root root 763 Sep 1 2012 . 0 drwxr-xr-x 1 root root 0 Jan 1 00:15 .. 2 -rw-r--r-- 1 root root 2281 Aug 21 2012 JQuerySpinBtn.css 7 -rw-r--r-- 1 root root 6880 Aug 21 2012 JQuerySpinBtn.js 18 -rw-r--r-- 1 root root 17987 Aug 21 2012 LICENSE.txt 0 -rw-r--r-- 1 root root 107 Aug 21 2012 bodybg.gif 39 -rw-r--r-- 1 root root 40289 Aug 21 2012 cambozola.jar 14 -rw-r--r-- 1 root root 14531 Aug 21 2012 control.htm 9 -rw-r--r-- 1 root root 8752 Aug 21 2012 example.jpg 0 -rw-r--r-- 1 root root 318 Aug 21 2012 favicon.ico 0 -rw-r--r-- 1 root root 233 Aug 21 2012 favicon.png 0 -rw-r--r-- 1 root root 123 Aug 21 2012 fix.css 2 -rw-r--r-- 1 root root 2114 Aug 21 2012 functions.js 3 -rw-r--r-- 1 root root 3058 Aug 21 2012 index.html 2 -rw-r--r-- 1 root root 2548 Aug 21 2012 java.html 6 -rw-r--r-- 1 root root 6361 Aug 21 2012 java_control.html 0 -rw-r--r-- 1 root root 302 Aug 21 2012 java_simple.html 5 -rw-r--r-- 1 root root 5429 Aug 21 2012 javascript.html 6 -rw-r--r-- 1 root root 6270 Aug 21 2012 javascript_motiondetection.html 2 -rw-r--r-- 1 root root 1620 Aug 21 2012 javascript_simple.html 70 -rw-r--r-- 1 root root 72174 Aug 21 2012 jquery.js 3 -rw-r--r-- 1 root root 2830 Aug 21 2012 jquery.rotate.js 4 -rw-r--r-- 1 root root 3987 Aug 21 2012 jquery.ui.core.min.js 21 -rw-r--r-- 1 root root 21090 Aug 21 2012 jquery.ui.custom.css 11 -rw-r--r-- 1 root root 11435 Aug 21 2012 jquery.ui.tabs.min.js 3 -rw-r--r-- 1 root root 2989 Aug 21 2012 jquery.ui.widget.min.js 3 -rw-r--r-- 1 root root 2962 Aug 21 2012 rotateicons.png 0 -rw-r--r-- 1 root root 35 Aug 21 2012 sidebarbg.gif 1 -rw-r--r-- 1 root root 1041 Aug 21 2012 spinbtn_updn.gif 2 -rw-r--r-- 1 root root 1773 Aug 21 2012 static.html 0 -rw-r--r-- 1 root root 329 Aug 21 2012 static_simple.html 3 -rw-r--r-- 1 root root 3053 Aug 21 2012 stream.html 0 -rw-r--r-- 1 root root 166 Aug 21 2012 stream_simple.html 5 -rw-r--r-- 1 root root 5157 Aug 21 2012 style.css 3 -rw-r--r-- 1 root root 2619 Aug 21 2012 videolan.html
— значит jQuery уже есть — тем лучше 🙂
# cat /www/webcam/jquery.js | head /*! * jQuery JavaScript Library v1.4.2 * http://jquery.com/ * * Copyright 2010, John Resig * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * Includes Sizzle.js * http://sizzlejs.com/
пример CGI-скрипта на bash
# cat /www/cgi-bin/uptime #!/bin/sh echo "Content-type: text/html" echo "" echo "<html><header></header><body>" echo "<h1>Uptime information</h1>" echo "Your embedded device has been running for:<pre><font color=Blue>" echo `uptime` echo "</font></pre>" echo "</body></html>"
скрипт mylua.cgi:
#!/bin/sh echo "Content-type: text/html" echo "" echo "<html><header></header><body><pre>" echo `env` echo `/root/lua -v` echo $QUERY_STRING echo $SCRIPT_DATA echo "</pre></body></html>"
ответ:
<html><header></header><body><pre> CONTENT_TYPE=application/x-www-form-urlencoded GATEWAY_INTERFACE=CGI/1.1 REMOTE_HOST=192.168.217.15 HTTP_AUTHORIZATION=Basic cm9vdDox REMOTE_USER=root REMOTE_ADDR=192.168.217.15 QUERY_STRING= HTTP_USER_AGENT=Mozilla/5.0 (Windows NT 5.1; rv:13.0) Gecko/20100101 Firefox/13.0.1 DOCUMENT_ROOT=/www REMOTE_PORT=1388 HTTP_ACCEPT=text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 CONTENT_LENGTH=233 SCRIPT_FILENAME=/www/cgi-bin/mylua.cgi HTTP_HOST=192.168.217.1 REQUEST_URI=/cgi-bin/mylua.cgi SERVER_SOFTWARE=uHTTPd HTTP_CONNECTION=keep-alive PATH=/sbin:/usr/sbin:/bin:/usr/bin HTTP_ACCEPT_LANGUAGE=ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3 HTTP_REFERER=http://192.168.217.1/mylua.html SERVER_PROTOCOL=HTTP/1.1 HTTP_ACCEPT_ENCODING=gzip, deflate REDIRECT_STATUS=200 REQUEST_METHOD=POST SERVER_ADDR=192.168.217.1 PWD=/www SERVER_PORT=80 SCRIPT_NAME=/cgi-bin/mylua.cgi SERVER_NAME=192.168.217.1 Lua 5.2.1 Copyright (C) 1994-2012 Lua.org, PUC-Rio </pre></body></html>
используем силу гугл и поищем про написание cgi на bash
нашёлся кусок кода для считывания данных POST и их декодирования:
if [ "$REQUEST_METHOD" = "POST" ]; then read POST_STRING while true; do HEX="$(echo "$POST_STRING" | sed 's/^.*[^%]%\([0-9a-fA-F][0-9a-fA-F]\).*/\1/')" if [ "$HEX" = "$POST_STRING" ]; then break; fi REP=$(echo -e \\x$HEX) # to avoid mishandling of %25 (== '%') replace all occurences of the # percent sign itself with a double percent sign (kind of escaping) [ "$REP" = "%" ] && REP="%%" POST_STRING="$(echo "$POST_STRING" | sed 's/^\(.*[^%]\)%\([0-9a-fA-F][0-9a-fA-F]\)/\1'$REP'/')" done # replace all escaped percent signs with a single percent sign POST_STRING=$(echo $POST_STRING | sed 's/%%/%/g') # replace all ampersands with spaces for easier handling later POST_STRING=$(echo $POST_STRING | sed 's/&/ /g') do_stuff fi
реализуем CGI для обработки и запуска Lua-скриптов.
запрос:
var='hello world!'; print(var); a='123'; print(a); b=tonumber(a); print(b); c=234; d=b+c; print(d); print("start lua..."); require('mytest'); res = mytest.add1(12); print(res); print("end lua...");
тестовый CGI — mylua.cgi
#!/bin/sh echo "Content-type: text/html" echo "" echo "<html><header></header><body><pre>" #echo `env` #echo `/root/lua -v` #echo $QUERY_STRING #echo $SCRIPT_DATA if [ "$REQUEST_METHOD" = "POST" ]; then read POST_STRING echo $POST_STRING echo "===" POST_STRING=$(echo $POST_STRING | sed 's/+/ /g') while true; do HEX="$(echo "$POST_STRING" | sed 's/^.*[^%]%\([0-9a-fA-F][0-9a-fA-F]\).*/\1/')" if [ "$HEX" = "$POST_STRING" ]; then break; fi REP=$(echo -e \\x$HEX) # to avoid mishandling of %25 (== '%') replace all occurences of the # percent sign itself with a double percent sign (kind of escaping) [ "$REP" = "%" ] && REP="%%" POST_STRING="$(echo "$POST_STRING" | sed 's/^\(.*[^%]\)%\([0-9a-fA-F][0-9a-fA-F]\)/\1'$REP'/')" done echo $POST_STRING echo "===" # replace all escaped percent signs with a single percent sign POST_STRING=$(echo $POST_STRING | sed 's/%%/%/g') # replace all ampersands with spaces for easier handling later POST_STRING=$(echo $POST_STRING | sed 's/&/ /g') POST_STRING=$(echo $POST_STRING | sed 's/SCRIPT_DATA=//g') echo $POST_STRING echo "==== RESULT ====" echo $POST_STRING > /tmp/tmpscript.lua export PATH="$/root:$PATH" cd /root echo `/root/lua /tmp/tmpscript.lua` fi echo "</pre></body></html>"
результат:
<html><header></header><body><pre> SCRIPT_DATA=var%3D'hello+world!'%3B%0Aprint(var)%3B%0Aa%3D'123'%3B%0Aprint(a)%3B%0Ab%3Dtonumber(a)%3B%0Aprint(b)%3B%0Ac%3D234%3B%0Ad%3Db%2Bc%3B%0Aprint(d)%3B%0A%0Aprint(%22start+lua...%22)%3B%0A%0Arequire('mytest')%3B%0Ares+%3D+mytest.add1(12)%3B%0Aprint(res)%3B%0Aprint(%22end+lua...%22)%3B%0A === SCRIPT_DATA=var='hello world!';print(var);a='123';print(a);b=tonumber(a);print(b);c=234;d=b+c;print(d);print("start lua...");require('mytest');res = mytest.add1(12);print(res);print("end lua..."); === var='hello world!';print(var);a='123';print(a);b=tonumber(a);print(b);c=234;d=b+c;print(d);print("start lua...");require('mytest');res = mytest.add1(12);print(res);print("end lua..."); ==== RESULT ==== hello world! 123 123 357 start lua... [i] test_add1(12.00) 13 end lua... </pre></body></html>
Что-то переносы строки никак не хотят работать 🙁
добавим форму для загрузки файла:
<hr/> <form action="/cgi-bin/myluafile.cgi" method=POST enctype="multipart/form-data"> <label style="font-size:14pt;">Select file with Lua script: </label> <input type="file" name="luafile" /> <input type="submit" value="Send file!" /> </form>
заливаем файлы
scp myluafile.cgi [email protected]:/www/cgi-bin/
scp mylua.html [email protected]:/www/
скрипт myluafile.cgi
#!/bin/sh echo "Content-type: text/html" echo "" echo "<html><header></header><body><pre>" killall lua echo `env` echo $QUERY_STRING echo "========" read Beg echo $Beg read ContentDisposition echo $ContentDisposition read ContentType echo $ContentType echo "" > /tmp/tmpscript.lua while read STR ; do echo $STR echo $STR >> /tmp/tmpscript.lua done if [ "$REQUEST_METHOD" = "POST" ]; then echo "========" export PATH="$/root:$PATH" cd /root echo `/root/lua /tmp/tmpscript.lua` fi echo "</pre></body></html>"
веб-страничка mylua.html:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>OR-WIFI-ROBOT: Lua script</title> <script src="./webcam/jquery.js"></script> <script type="text/javascript"> function sendScript(){ //alert("setSettings"); var scr_data = $("#luascriptData").val(); // if( console && console.log ) { // console.log("sendScript"); // console.log(scr_data); // } $("#luascriptData").css("background-color", "yellow"); $("#scriptResult").val(""); $.ajax({ type: "POST", url: "/cgi-bin/mylua.cgi", dataType: "html", data: {SCRIPT_DATA : scr_data}, success: function ( data ) { $("#luascriptData").css("background-color", "white"); // if( console && console.log ) { // console.log(data); // } //alert(data); $("#scriptResult").val(data); } }); } </script> </head> <body> <table> <tr> <td> <label style="font-size:14pt;">Lua script:</label> <textarea id="luascriptData" name="SCRIPT_DATA" rows="20" cols="80"> var='hello world!'; print(var); a='123'; print(a); b=tonumber(a); print(b); c=234; d=b+c; print(d); </textarea> </td> <td> <label style="font-size:14pt;">Result:</label> <textarea id="scriptResult" rows="20" cols="80" style="" > </textarea> </td> </tr> <tr> <td><input type="submit" value="Send" onclick="sendScript(); return false;" /></td> <td></td> </tr> </table> <hr/> <form action="/cgi-bin/myluafile.cgi" method=POST enctype="multipart/form-data"> <label style="font-size:14pt;">Select file with Lua script: </label> <input type="file" name="luafile" /> <input type="submit" value="Send file!" /> </form> <hr/> <a href="index.html">home</a> <a href="admin/index.html">administration</a> <a href="https://robocraft.ru">RoboCraft</a> </body> </html>
— в ней же виден javascript-код для jQuery, реализующий ajax-запрос к нашему CGI-скрипту /cgi-bin/mylua.cgi
ответ скрипта на загрузку файла blink.lua (414 байт):
CONTENT_TYPE=multipart/form-data; boundary=---------------------------4827543632391 GATEWAY_INTERFACE=CGI/1.1 REMOTE_HOST=192.168.217.15 HTTP_AUTHORIZATION=Basic cm9vdDox REMOTE_USER=root REMOTE_ADDR=192.168.217.15 QUERY_STRING= HTTP_USER_AGENT=Mozilla/5.0 (Windows NT 5.1; rv:13.0) Gecko/20100101 Firefox/13.0.1 DOCUMENT_ROOT=/www REMOTE_PORT=2592 HTTP_ACCEPT=text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 CONTENT_LENGTH=618 SCRIPT_FILENAME=/www/cgi-bin/myluafile.cgi HTTP_HOST=192.168.217.1 REQUEST_URI=/cgi-bin/myluafile.cgi SERVER_SOFTWARE=uHTTPd HTTP_CONNECTION=keep-alive PATH=/sbin:/usr/sbin:/bin:/usr/bin HTTP_ACCEPT_LANGUAGE=ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3 HTTP_REFERER=http://192.168.217.1/mylua.html SERVER_PROTOCOL=HTTP/1.1 HTTP_ACCEPT_ENCODING=gzip, deflate REDIRECT_STATUS=200 REQUEST_METHOD=POST SERVER_ADDR=192.168.217.1 PWD=/www SERVER_PORT=80 SCRIPT_NAME=/cgi-bin/myluafile.cgi SERVER_NAME=192.168.217.1 ======== -----------------------------4827543632391 Content-Disposition: form-data; name="luafile"; filename="blink.lua" Content-Type: application/octet-stream --[[ blink ]]-- led=io.open("/sys/devices/platform/leds-gpio/leds/tp-link:green:3g/brightness", "w"); if led==nil then print("Error open file!"); os.exit(-1); end val = 0; t0 = os.time(); t1 = 0; while 1 do t1 = os.time(); led:seek(beg, 0); if t1 > t0 then t0 = t1; print(val); led:write(val); if val == 0 then val = 1; else val = 0; end end end -----------------------------4827543632391-- ========
блинк пошёл :))
разумеется, нужно делать проверки, правильно считывать и отбрасывать последнюю строчку, но последняя строчка всё равно будет принята за комментарий 😉
Файлы:
mylua.cgi
myluafile.cgi
mylua.html
Ссылки
http://jquery.com
По теме
Использование Lua в робототехнике
Исследование Wi-Fi-роутера TP-LINK TL-MR3020
Кросс-компиляция Lua для TP-LINK TL-MR3020
Lua — модуль для работы с последовательным портом