Replaces WebServer with httpd.
This commit is contained in:
@ -1,4 +1,4 @@
|
|||||||
VERSION=7.0.5
|
VERSION=7.0.6
|
||||||
REVISION=$(shell git rev-parse HEAD)
|
REVISION=$(shell git rev-parse HEAD)
|
||||||
|
|
||||||
OUT = out
|
OUT = out
|
||||||
@ -128,8 +128,8 @@ POSIX_BOOT = common/boot.fs common/conditionals.fs common/vocabulary.fs \
|
|||||||
posix/posix.fs posix/posix_highlevel.fs posix/termios.fs common/locals.fs \
|
posix/posix.fs posix/posix_highlevel.fs posix/termios.fs common/locals.fs \
|
||||||
common/tasks.fs common/utils.fs common/highlevel.fs common/filetools.fs \
|
common/tasks.fs common/utils.fs common/highlevel.fs common/filetools.fs \
|
||||||
posix/posix_desktop.fs \
|
posix/posix_desktop.fs \
|
||||||
common/streams.fs common/blocks.fs posix/telnetd.fs \
|
common/streams.fs common/blocks.fs \
|
||||||
posix/sockets.fs posix/httpd.fs posix/web_interface.fs \
|
posix/sockets.fs posix/telnetd.fs posix/httpd.fs posix/web_interface.fs \
|
||||||
posix/autoboot.fs \
|
posix/autoboot.fs \
|
||||||
common/fini.fs
|
common/fini.fs
|
||||||
$(GEN)/posix_boot.h: common/source_to_string.js $(POSIX_BOOT) | $(GEN)
|
$(GEN)/posix_boot.h: common/source_to_string.js $(POSIX_BOOT) | $(GEN)
|
||||||
@ -148,9 +148,9 @@ ESP32_BOOT = common/boot.fs common/conditionals.fs common/vocabulary.fs \
|
|||||||
common/tasks.fs esp32/platform.fs esp32/highlevel.fs \
|
common/tasks.fs esp32/platform.fs esp32/highlevel.fs \
|
||||||
esp32/bindings.fs common/highlevel.fs \
|
esp32/bindings.fs common/highlevel.fs \
|
||||||
common/filetools.fs common/utils.fs common/locals.fs \
|
common/filetools.fs common/utils.fs common/locals.fs \
|
||||||
common/streams.fs esp32/web_interface.fs \
|
common/streams.fs posix/httpd.fs posix/web_interface.fs esp32/web_interface.fs \
|
||||||
esp32/registers.fs esp32/timers.fs \
|
esp32/registers.fs esp32/timers.fs \
|
||||||
esp32/bterm.fs esp32/telnetd.fs \
|
esp32/bterm.fs posix/telnetd.fs \
|
||||||
esp32/camera.fs common/blocks.fs \
|
esp32/camera.fs common/blocks.fs \
|
||||||
esp32/autoboot.fs common/fini.fs
|
esp32/autoboot.fs common/fini.fs
|
||||||
$(GEN)/esp32_boot.h: common/source_to_string.js $(ESP32_BOOT) | $(GEN)
|
$(GEN)/esp32_boot.h: common/source_to_string.js $(ESP32_BOOT) | $(GEN)
|
||||||
|
|||||||
@ -79,11 +79,21 @@ forth definitions
|
|||||||
|
|
||||||
vocabulary sockets sockets definitions
|
vocabulary sockets sockets definitions
|
||||||
transfer{
|
transfer{
|
||||||
socket bind listen connect accept select poll errno
|
socket bind listen connect sockaccept select poll errno
|
||||||
}transfer
|
}transfer
|
||||||
1 constant SOCK_STREAM
|
1 constant SOCK_STREAM
|
||||||
2 constant AF_INET
|
2 constant AF_INET
|
||||||
16 constant sizeof(sockaddr_in)
|
16 constant sizeof(sockaddr_in)
|
||||||
|
1 constant SOL_SOCKET
|
||||||
|
2 constant SO_REUSEADDR
|
||||||
|
|
||||||
|
: bs, ( n -- ) dup 256 / c, c, ;
|
||||||
|
: s, ( n -- ) dup c, 256 / c, ;
|
||||||
|
: l, ( n -- ) dup s, 65536 / s, ;
|
||||||
|
: sockaddr create 16 c, AF_INET c, 0 bs, 0 l, 0 l, 0 l, ;
|
||||||
|
: ->port@ ( a -- n ) 2 + >r r@ c@ 256 * r> 1+ c@ + ;
|
||||||
|
: ->port! ( n a -- ) 2 + >r dup 256 / r@ c! r> 1+ c! ;
|
||||||
|
|
||||||
forth definitions
|
forth definitions
|
||||||
|
|
||||||
vocabulary interrupts interrupts definitions
|
vocabulary interrupts interrupts definitions
|
||||||
|
|||||||
@ -8,15 +8,19 @@ forth definitions
|
|||||||
( Set up Basic I/O )
|
( Set up Basic I/O )
|
||||||
internals definitions
|
internals definitions
|
||||||
: esp32-bye 0 terminate ;
|
: esp32-bye 0 terminate ;
|
||||||
' esp32-bye is bye
|
|
||||||
: serial-type ( a n -- ) Serial.write drop ;
|
: serial-type ( a n -- ) Serial.write drop ;
|
||||||
' serial-type is type
|
|
||||||
: serial-key ( -- n )
|
: serial-key ( -- n )
|
||||||
begin pause Serial.available until 0 >r rp@ 1 Serial.readBytes drop r> ;
|
begin pause Serial.available until 0 >r rp@ 1 Serial.readBytes drop r> ;
|
||||||
' serial-key is key
|
|
||||||
: serial-key? ( -- n ) Serial.available ;
|
: serial-key? ( -- n ) Serial.available ;
|
||||||
' serial-key? is key?
|
also forth definitions
|
||||||
forth definitions
|
: default-type serial-type ;
|
||||||
|
: default-key serial-key ;
|
||||||
|
: default-key? serial-key? ;
|
||||||
|
' default-type is type
|
||||||
|
' default-key is key
|
||||||
|
' default-key? is key?
|
||||||
|
' esp32-bye is bye
|
||||||
|
only forth definitions
|
||||||
|
|
||||||
( Map Arduino / ESP32 things to shorter names. )
|
( Map Arduino / ESP32 things to shorter names. )
|
||||||
: pin ( n pin# -- ) swap digitalWrite ;
|
: pin ( n pin# -- ) swap digitalWrite ;
|
||||||
|
|||||||
@ -1,42 +0,0 @@
|
|||||||
( Telnet )
|
|
||||||
vocabulary telnetd telnetd definitions also sockets also internals
|
|
||||||
|
|
||||||
23 constant port
|
|
||||||
-1 value sockfd -1 value clientfd
|
|
||||||
: bs, ( n -- ) dup 256 / c, c, ;
|
|
||||||
: s, ( n -- ) dup c, 256 / c, ;
|
|
||||||
: l, ( n -- ) dup s, 65536 / s, ;
|
|
||||||
create telnet-port 16 c, AF_INET c, port bs, 0 l, 0 l, 0 l,
|
|
||||||
create client sizeof(sockaddr_in) allot variable client-len
|
|
||||||
|
|
||||||
defer broker
|
|
||||||
|
|
||||||
: telnet-emit' ( ch -- ) >r rp@ 1 clientfd write-file rdrop if broker then ;
|
|
||||||
: telnet-emit ( ch -- ) dup nl = if 13 telnet-emit' then telnet-emit' ;
|
|
||||||
: telnet-type ( a n -- ) for aft dup c@ telnet-emit 1+ then next drop ;
|
|
||||||
: telnet-key ( -- n ) 0 >r rp@ 1 clientfd read-file if drop rdrop broker else drop then r> ;
|
|
||||||
|
|
||||||
: connection ( n -- )
|
|
||||||
dup 0< if drop exit then to clientfd
|
|
||||||
0 echo !
|
|
||||||
['] telnet-key is key
|
|
||||||
['] telnet-type is type quit ;
|
|
||||||
|
|
||||||
: broker-connection
|
|
||||||
rp0 rp! sp0 sp!
|
|
||||||
begin
|
|
||||||
['] serial-key is key
|
|
||||||
['] serial-type is type
|
|
||||||
-1 echo !
|
|
||||||
." Listening on port " port . cr
|
|
||||||
sockfd client client-len accept
|
|
||||||
." Connected: " dup . cr connection
|
|
||||||
again ;
|
|
||||||
' broker-connection is broker
|
|
||||||
|
|
||||||
: server
|
|
||||||
AF_INET SOCK_STREAM 0 socket to sockfd
|
|
||||||
sockfd telnet-port sizeof(sockaddr_in) bind throw
|
|
||||||
sockfd 10 listen throw broker ;
|
|
||||||
|
|
||||||
only forth definitions
|
|
||||||
@ -221,10 +221,11 @@
|
|||||||
# include <sys/poll.h>
|
# include <sys/poll.h>
|
||||||
# define OPTIONAL_SOCKETS_SUPPORT \
|
# define OPTIONAL_SOCKETS_SUPPORT \
|
||||||
Y(socket, n0 = socket(n2, n1, n0); NIPn(2)) \
|
Y(socket, n0 = socket(n2, n1, n0); NIPn(2)) \
|
||||||
|
Y(setsockopt, n0 = setsockopt(n4, n3, n2, a1, n0); NIPn(4)) \
|
||||||
Y(bind, n0 = bind(n2, (struct sockaddr *) a1, n0); NIPn(2)) \
|
Y(bind, n0 = bind(n2, (struct sockaddr *) a1, n0); NIPn(2)) \
|
||||||
Y(listen, n0 = listen(n1, n0); NIP) \
|
Y(listen, n0 = listen(n1, n0); NIP) \
|
||||||
Y(connect, n0 = connect(n2, (struct sockaddr *) a1, n0); NIPn(2)) \
|
Y(connect, n0 = connect(n2, (struct sockaddr *) a1, n0); NIPn(2)) \
|
||||||
Y(accept, n0 = accept(n2, (struct sockaddr *) a1, (socklen_t *) a0); NIPn(2)) \
|
Y(sockaccept, n0 = accept(n2, (struct sockaddr *) a1, (socklen_t *) a0); NIPn(2)) \
|
||||||
Y(select, n0 = select(n4, (fd_set *) a3, (fd_set *) a2, (fd_set *) a1, (struct timeval *) a0); NIPn(4)) \
|
Y(select, n0 = select(n4, (fd_set *) a3, (fd_set *) a2, (fd_set *) a1, (struct timeval *) a0); NIPn(4)) \
|
||||||
Y(poll, n0 = poll((struct pollfd *) a2, (nfds_t) n1, n0); NIPn(2)) \
|
Y(poll, n0 = poll((struct pollfd *) a2, (nfds_t) n1, n0); NIPn(2)) \
|
||||||
Y(errno, PUSH errno)
|
Y(errno, PUSH errno)
|
||||||
|
|||||||
@ -1,156 +1,16 @@
|
|||||||
( Server Terminal )
|
( Server Terminal )
|
||||||
|
|
||||||
also streams also WebServer also WiFi
|
also streams also WiFi also web-interface definitions
|
||||||
vocabulary web-interface also web-interface definitions
|
|
||||||
|
|
||||||
: ip# dup 255 and n. [char] . emit 256 / ;
|
: ip# dup 255 and n. [char] . emit 256 / ;
|
||||||
: ip. ( n -- ) ip# ip# ip# 255 and . ;
|
: ip. ( n -- ) ip# ip# ip# 255 and . ;
|
||||||
|
|
||||||
r|
|
|
||||||
<!html>
|
|
||||||
<head>
|
|
||||||
<title>esp32forth</title>
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
padding: 5px;
|
|
||||||
background-color: #111;
|
|
||||||
color: #2cf;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
#prompt {
|
|
||||||
width: 100%;
|
|
||||||
padding: 5px;
|
|
||||||
font-family: monospace;
|
|
||||||
background-color: #ff8;
|
|
||||||
}
|
|
||||||
#output {
|
|
||||||
width: 100%;
|
|
||||||
height: 80%;
|
|
||||||
resize: none;
|
|
||||||
overflow-y: scroll;
|
|
||||||
word-break: break-all;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<link rel="icon" href="data:,">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h2>ESP32forth v7</h2>
|
|
||||||
Upload File: <input id="filepick" type="file" name="files[]"></input><br/>
|
|
||||||
<button onclick="ask('hex')">hex</button>
|
|
||||||
<button onclick="ask('decimal')">decimal</button>
|
|
||||||
<button onclick="ask('words')">words</button>
|
|
||||||
<button onclick="ask('low led pin')">LED OFF</button>
|
|
||||||
<button onclick="ask('high led pin')">LED ON</button>
|
|
||||||
<br/>
|
|
||||||
<textarea id="output" readonly></textarea>
|
|
||||||
<input id="prompt" type="prompt"></input><br/>
|
|
||||||
<script>
|
|
||||||
var prompt = document.getElementById('prompt');
|
|
||||||
var filepick = document.getElementById('filepick');
|
|
||||||
var output = document.getElementById('output');
|
|
||||||
function httpPost(url, items, callback) {
|
|
||||||
var fd = new FormData();
|
|
||||||
for (k in items) {
|
|
||||||
fd.append(k, items[k]);
|
|
||||||
}
|
|
||||||
var r = new XMLHttpRequest();
|
|
||||||
r.onreadystatechange = function() {
|
|
||||||
if (this.readyState == XMLHttpRequest.DONE) {
|
|
||||||
if (this.status === 200) {
|
|
||||||
callback(this.responseText);
|
|
||||||
} else {
|
|
||||||
callback(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
r.open('POST', url);
|
|
||||||
r.send(fd);
|
|
||||||
}
|
|
||||||
function ask(cmd, callback) {
|
|
||||||
httpPost('/input',
|
|
||||||
{cmd: cmd + '\n'}, function(data) {
|
|
||||||
if (data !== null) { output.value += data; }
|
|
||||||
output.scrollTop = output.scrollHeight; // Scroll to the bottom
|
|
||||||
if (callback !== undefined) { callback(); }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
prompt.onkeyup = function(event) {
|
|
||||||
if (event.keyCode === 13) {
|
|
||||||
event.preventDefault();
|
|
||||||
ask(prompt.value);
|
|
||||||
prompt.value = '';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
filepick.onchange = function(event) {
|
|
||||||
if (event.target.files.length > 0) {
|
|
||||||
var reader = new FileReader();
|
|
||||||
reader.onload = function(e) {
|
|
||||||
var parts = e.target.result.replace(/[\r]/g, '').split('\n');
|
|
||||||
function upload() {
|
|
||||||
if (parts.length === 0) { filepick.value = ''; return; }
|
|
||||||
ask(parts.shift(), upload);
|
|
||||||
}
|
|
||||||
upload();
|
|
||||||
}
|
|
||||||
reader.readAsText(event.target.files[0]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
window.onload = function() {
|
|
||||||
ask('');
|
|
||||||
prompt.focus();
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
| s>z constant index-html
|
|
||||||
|
|
||||||
variable webserver
|
|
||||||
20000 constant out-size
|
|
||||||
200 stream input-stream
|
|
||||||
out-size stream output-stream
|
|
||||||
create out-string out-size 1+ allot align
|
|
||||||
|
|
||||||
: handle-index
|
|
||||||
index-html z>s nip webserver @ WebServer.setContentLength
|
|
||||||
200 z" text/html" index-html webserver @ WebServer.send
|
|
||||||
;
|
|
||||||
|
|
||||||
: handle-input
|
|
||||||
z" cmd" webserver @ WebServer.hasArg if
|
|
||||||
z" cmd" webserver @ WebServer.arg input-stream >stream pause
|
|
||||||
out-string out-size output-stream stream>
|
|
||||||
200 z" text/plain" out-string webserver @ WebServer.send
|
|
||||||
else
|
|
||||||
500 z" text/plain" z" Missing Input" webserver @ WebServer.send
|
|
||||||
then
|
|
||||||
;
|
|
||||||
|
|
||||||
: serve-type ( a n -- ) output-stream >stream ;
|
|
||||||
: serve-key ( -- n ) input-stream stream>ch ;
|
|
||||||
|
|
||||||
: do-serve
|
|
||||||
80 WebServer.new webserver !
|
|
||||||
z" /" ['] handle-index webserver @ WebServer.on
|
|
||||||
z" /input" ['] handle-input webserver @ WebServer.on
|
|
||||||
webserver @ WebServer.begin
|
|
||||||
begin
|
|
||||||
webserver @ WebServer.handleClient
|
|
||||||
pause
|
|
||||||
again
|
|
||||||
;
|
|
||||||
|
|
||||||
' do-serve 1000 1000 task webserver-task
|
|
||||||
|
|
||||||
: serve
|
|
||||||
['] serve-type is type
|
|
||||||
['] serve-key is key
|
|
||||||
webserver-task start-task
|
|
||||||
;
|
|
||||||
|
|
||||||
also forth definitions
|
also forth definitions
|
||||||
|
|
||||||
: login ( z z -- )
|
: login ( z z -- )
|
||||||
WIFI_MODE_STA Wifi.mode
|
WIFI_MODE_STA Wifi.mode
|
||||||
WiFi.begin begin WiFi.localIP 0= while 100 ms repeat WiFi.localIP ip. cr
|
WiFi.begin begin WiFi.localIP 0= while 100 ms repeat WiFi.localIP ip. cr
|
||||||
z" forth" MDNS.begin if ." MDNS started" else ." MDNS failed" then cr ;
|
z" forth" MDNS.begin if ." MDNS started" else ." MDNS failed" then cr ;
|
||||||
: webui ( z z -- ) login serve ;
|
: webui ( z z -- ) login 80 server ;
|
||||||
|
|
||||||
only forth definitions
|
only forth definitions
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
( HTTP Daemon )
|
( HTTP Daemon )
|
||||||
|
vocabulary httpd httpd definitions also sockets
|
||||||
vocabulary httpd httpd definitions also posix
|
|
||||||
|
|
||||||
1 constant max-connections
|
1 constant max-connections
|
||||||
2048 constant chunk-size
|
2048 constant chunk-size
|
||||||
@ -8,32 +7,25 @@ create chunk chunk-size allot
|
|||||||
0 value chunk-filled
|
0 value chunk-filled
|
||||||
|
|
||||||
-1 value sockfd -1 value clientfd
|
-1 value sockfd -1 value clientfd
|
||||||
: bs, ( n -- ) dup 256 / c, c, ;
|
sockaddr httpd-port sockaddr client variable client-len
|
||||||
: s, ( n -- ) dup c, 256 / c, ;
|
|
||||||
: l, ( n -- ) dup s, 65536 / s, ;
|
|
||||||
create httpd-port AF_INET s, here 0 bs, 0 l, 0 , constant port
|
|
||||||
: port@ ( -- n ) port c@ 256 * port 1+ c@ + ;
|
|
||||||
: port! ( n -- ) dup 256 / port c! port 1+ c! ;
|
|
||||||
create client sizeof(sockaddr_in) allot variable client-len
|
|
||||||
|
|
||||||
: client-type ( a n -- ) clientfd -rot write 0< if 2drop 1 throw then ;
|
: client-type ( a n -- ) clientfd write-file throw ;
|
||||||
: client-read ( -- n ) 0 >r clientfd rp@ 1 read 0< if rdrop 1 throw then r> ;
|
: client-read ( -- n ) 0 >r rp@ 1 clientfd read-file throw 1 <> throw ;
|
||||||
: client-emit ( ch -- ) >r rp@ 1 client-type rdrop ;
|
: client-emit ( ch -- ) >r rp@ 1 client-type rdrop ;
|
||||||
: client-cr 13 client-emit nl client-emit ;
|
: client-cr 13 client-emit nl client-emit ;
|
||||||
|
|
||||||
: handleClient
|
: handleClient
|
||||||
clientfd close drop
|
clientfd close-file drop
|
||||||
sockfd client client-len accept
|
sockfd client client-len sockaccept
|
||||||
dup 0< if drop exit then to clientfd
|
dup 0< if drop exit then to clientfd
|
||||||
chunk chunk-size 0 fill
|
chunk chunk-size 0 fill
|
||||||
clientfd chunk chunk-size read to chunk-filled
|
chunk chunk-size clientfd read-file throw to chunk-filled
|
||||||
( chunk chunk-filled type cr )
|
|
||||||
;
|
;
|
||||||
|
|
||||||
: serve ( port -- )
|
: server ( port -- )
|
||||||
port! ." Listening on port " port@ . cr
|
httpd-port ->port! ." Listening on port " httpd-port ->port@ . cr
|
||||||
AF_INET SOCK_STREAM 0 socket to sockfd
|
AF_INET SOCK_STREAM 0 socket to sockfd
|
||||||
sockfd SOL_SOCKET SO_REUSEADDR 1 >r rp@ 4 setsockopt rdrop throw
|
( sockfd SOL_SOCKET SO_REUSEADDR 1 >r rp@ 4 setsockopt rdrop throw )
|
||||||
sockfd httpd-port sizeof(sockaddr_in) bind throw
|
sockfd httpd-port sizeof(sockaddr_in) bind throw
|
||||||
sockfd max-connections listen throw
|
sockfd max-connections listen throw
|
||||||
;
|
;
|
||||||
|
|||||||
@ -85,10 +85,15 @@ decimal
|
|||||||
|
|
||||||
( Hookup I/O )
|
( Hookup I/O )
|
||||||
: stdout-write ( a n -- ) stdout -rot write drop ;
|
: stdout-write ( a n -- ) stdout -rot write drop ;
|
||||||
' stdout-write is type
|
|
||||||
: stdin-key ( -- n ) 0 >r stdin rp@ 1 read drop r> ;
|
: stdin-key ( -- n ) 0 >r stdin rp@ 1 read drop r> ;
|
||||||
' stdin-key is key
|
|
||||||
: posix-bye 0 sysexit ;
|
: posix-bye 0 sysexit ;
|
||||||
|
|
||||||
|
also forth definitions
|
||||||
|
: default-type stdout-write ;
|
||||||
|
: default-key stdin-key ;
|
||||||
|
only posix definitions
|
||||||
|
' default-type is type
|
||||||
|
' default-key is key
|
||||||
' posix-bye is bye
|
' posix-bye is bye
|
||||||
|
|
||||||
( I/O Error Helpers )
|
( I/O Error Helpers )
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
( Sockets )
|
( Sockets )
|
||||||
posix definitions
|
vocabulary sockets sockets definitions also posix
|
||||||
|
|
||||||
z" socket" 3 sysfunc socket
|
z" socket" 3 sysfunc socket
|
||||||
z" bind" 3 sysfunc bind
|
z" bind" 3 sysfunc bind
|
||||||
z" listen" 2 sysfunc listen
|
z" listen" 2 sysfunc listen
|
||||||
z" connect" 3 sysfunc connect
|
z" connect" 3 sysfunc connect
|
||||||
z" accept" 3 sysfunc accept
|
z" accept" 3 sysfunc sockaccept
|
||||||
z" poll" 3 sysfunc poll
|
z" poll" 3 sysfunc poll
|
||||||
z" setsockopt" 5 sysfunc setsockopt
|
z" setsockopt" 5 sysfunc setsockopt
|
||||||
|
|
||||||
@ -15,4 +15,11 @@ z" setsockopt" 5 sysfunc setsockopt
|
|||||||
1 constant SOL_SOCKET
|
1 constant SOL_SOCKET
|
||||||
2 constant SO_REUSEADDR
|
2 constant SO_REUSEADDR
|
||||||
|
|
||||||
|
: bs, ( n -- ) dup 256 / c, c, ;
|
||||||
|
: s, ( n -- ) dup c, 256 / c, ;
|
||||||
|
: l, ( n -- ) dup s, 65536 / s, ;
|
||||||
|
: sockaddr create AF_INET s, 0 bs, 0 l, 0 l, 0 l, ;
|
||||||
|
: ->port@ ( a -- n ) 2 + >r r@ c@ 256 * r> 1+ c@ + ;
|
||||||
|
: ->port! ( n a -- ) 2 + >r dup 256 / r@ c! r> 1+ c! ;
|
||||||
|
|
||||||
forth definitions
|
forth definitions
|
||||||
|
|||||||
@ -1,40 +1,38 @@
|
|||||||
( Telnet )
|
( Telnet )
|
||||||
include posix/sockets.fs
|
|
||||||
|
|
||||||
vocabulary telnetd telnetd definitions also posix
|
vocabulary telnetd telnetd definitions also sockets
|
||||||
|
|
||||||
5555 constant port
|
|
||||||
-1 value sockfd -1 value clientfd
|
-1 value sockfd -1 value clientfd
|
||||||
: bs, ( n -- ) dup 256 / c, c, ;
|
sockaddr telnet-port sockaddr client variable client-len
|
||||||
: s, ( n -- ) dup c, 256 / c, ;
|
|
||||||
: l, ( n -- ) dup s, 65536 / s, ;
|
|
||||||
create telnet-port AF_INET s, port bs, 0 l, 0 ,
|
|
||||||
create client sizeof(sockaddr_in) allot variable client-len
|
|
||||||
|
|
||||||
defer broker
|
defer broker
|
||||||
|
|
||||||
: telnet-type ( a n -- ) clientfd -rot write 0< if 2drop broker then ;
|
: telnet-emit' ( ch -- ) >r rp@ 1 clientfd write-file rdrop if broker then ;
|
||||||
: telnet-key ( -- n ) 0 >r clientfd rp@ 1 read 0< if rdrop broker then r> ;
|
: telnet-emit ( ch -- ) dup nl = if 13 telnet-emit' then telnet-emit' ;
|
||||||
|
: telnet-type ( a n -- ) for aft dup c@ telnet-emit 1+ then next drop ;
|
||||||
|
: telnet-key ( -- n ) 0 >r rp@ 1 clientfd read-file swap 1 <> or if rdrop broker then r> ;
|
||||||
|
|
||||||
: connection ( n -- )
|
: connection ( n -- )
|
||||||
dup 0< if drop exit then to clientfd
|
dup 0< if drop exit then to clientfd
|
||||||
|
0 echo !
|
||||||
['] telnet-key is key
|
['] telnet-key is key
|
||||||
['] telnet-type is type quit ;
|
['] telnet-type is type quit ;
|
||||||
|
|
||||||
: broker-connection
|
: broker-connection
|
||||||
rp0 rp! sp0 sp!
|
rp0 rp! sp0 sp!
|
||||||
begin
|
begin
|
||||||
['] stdin-key is key ['] stdout-write is type
|
['] default-key is key ['] default-type is type
|
||||||
." Listening on port " port . cr
|
-1 echo !
|
||||||
sockfd client client-len accept
|
." Listening on port " telnet-port ->port@ . cr
|
||||||
|
sockfd client client-len sockaccept
|
||||||
." Connected: " dup . cr connection
|
." Connected: " dup . cr connection
|
||||||
again ;
|
again ;
|
||||||
' broker-connection is broker
|
' broker-connection is broker
|
||||||
|
|
||||||
: server
|
: server ( port -- )
|
||||||
|
telnet-port ->port!
|
||||||
AF_INET SOCK_STREAM 0 socket to sockfd
|
AF_INET SOCK_STREAM 0 socket to sockfd
|
||||||
sockfd telnet-port sizeof(sockaddr_in) bind throw
|
sockfd telnet-port sizeof(sockaddr_in) bind throw
|
||||||
sockfd 10 listen throw broker ;
|
sockfd 1 listen throw broker ;
|
||||||
|
|
||||||
only forth definitions
|
only forth definitions
|
||||||
|
|
||||||
|
|||||||
@ -125,8 +125,8 @@ create out-string out-size 1+ allot align
|
|||||||
: do-serve begin handle1 pause again ;
|
: do-serve begin handle1 pause again ;
|
||||||
' do-serve 1000 1000 task webserver-task
|
' do-serve 1000 1000 task webserver-task
|
||||||
|
|
||||||
: serve ( port -- )
|
: server ( port -- )
|
||||||
serve
|
server
|
||||||
['] serve-type is type
|
['] serve-type is type
|
||||||
['] serve-key is key
|
['] serve-key is key
|
||||||
webserver-task start-task
|
webserver-task start-task
|
||||||
|
|||||||
Reference in New Issue
Block a user