CraftDuino v2.0
  • - это CraftDuino - наш вариант полностью Arduino-совместимой платы.
  • CraftDuino - настоящий конструктор, для очень быстрого прототипирования и реализации идей.
  • Любая возможность автоматизировать что-то с лёгкостью реализуется с CraftDuino!
Просто добавьте CraftDuino!

Запуск своих CGI на Wi-Fi-роутере TP-LINK TL-MR3020



Продолжим небольшое программное исследование Wi-Fi-роутера TP-LINK TL-MR3020 под управлением OR-WRT (редакция OpenWrt от робофорума).

Сначала посмотрим те конфигурационные файлы, которые я забыл показать в прошлой статье-исследовании.
login as: root
root@192.168.217.1'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>:<state>:<timeout>:<device>:<options>
#     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/<device>.
#
#     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 name>: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:<name>: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 root@192.168.217.1:/www/cgi-bin/
scp mylua.html root@192.168.217.1:/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="http://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

Ссылки:
jquery.com

По теме:
Использование Lua в робототехнике
Исследование Wi-Fi-роутера TP-LINK TL-MR3020
Кросс-компиляция Lua для TP-LINK TL-MR3020
Lua — модуль для работы с последовательным портом
  • 0
  • 7 января 2013, 22:32
  • noonv

Комментарии (0)

RSS свернуть / развернуть

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.