|
(import (chicken tcp) |
|
(chicken foreign) |
|
(chicken string) |
|
(chicken port) |
|
(chicken io) |
|
(chicken pretty-print) |
|
(chicken condition) |
|
(chicken irregex) |
|
srfi-4 |
|
srfi-13 |
|
srfi-18 |
|
stb-image-write) |
|
|
|
(define (p . args) |
|
(display (apply conc args)) |
|
(flush-output)) |
|
|
|
(define (fail . args) |
|
(apply p args) |
|
(p "\n") |
|
(read-line) |
|
(exit -1)) |
|
|
|
(cond-expand |
|
(windows |
|
(foreign-declare "#include \"gdigrab.c\"") |
|
(define screen-w (foreign-lambda int "screen_w")) |
|
(define screen-h (foreign-lambda int "screen_h")) |
|
(define ss! (foreign-lambda void "GetScreenShot" u8vector int int))) |
|
(else |
|
(define screen-w (lambda () 32)) |
|
(define screen-h (lambda () 16)) |
|
(define ss! (lambda (u8vector int int) #f)))) |
|
|
|
(define externalport 8088) |
|
(define serverport 8088) |
|
|
|
(foreign-declare " |
|
#include <miniupnpc/miniupnpc.h> |
|
#include <miniupnpc/upnpcommands.h> |
|
") |
|
|
|
;; quick and dirty NAT external port take-over |
|
(define (nat-port-map iport eport #!optional |
|
(rootdescurl "http://192.168.0.1:80/RootDevice.xml")) |
|
|
|
(let ((result |
|
((foreign-lambda* int (((const c-string) rootdescurl) |
|
((const c-string) iport) |
|
((const c-string) eport)) |
|
" |
|
struct UPNPUrls urls; |
|
struct IGDdatas data; |
|
char lanaddr[64] = \"\"; |
|
int r; |
|
|
|
if(!UPNP_GetIGDFromUrl(rootdescurl, &urls, &data, lanaddr, sizeof(lanaddr))) |
|
return -2; |
|
|
|
// overwrite existing entry |
|
UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, |
|
eport, \"TCP\", 0); |
|
|
|
return(UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, |
|
iport, eport, lanaddr, \"ss alf\", |
|
\"TCP\", 0, \"0\")); |
|
") |
|
rootdescurl iport eport))) |
|
(unless (zero? result) |
|
(fail "obs! kunne ikke sette opp NAT: " result)))) |
|
|
|
;; fetch our external IP address from IGD router |
|
(define (external-ip #!optional |
|
(rootdescurl "http://192.168.0.1:80/RootDevice.xml")) |
|
|
|
(let* ((eip (make-string 64 #\null)) |
|
(result |
|
((foreign-lambda* int ((c-string rootdescurl) |
|
((c-pointer char) dest_ip)) |
|
" |
|
struct UPNPUrls urls; |
|
struct IGDdatas data; |
|
|
|
if(!UPNP_GetIGDFromUrl(rootdescurl, &urls, &data, 0, 0)) |
|
return -1; |
|
|
|
return(UPNP_GetExternalIPAddress(urls.controlURL, |
|
data.first.servicetype, |
|
dest_ip));") |
|
rootdescurl (location eip)))) |
|
(if (zero? result) |
|
(string-filter (lambda (x) (not (eq? #\null x))) eip) |
|
(fail "OBS! fant ingen ekstern IP fra router.")))) |
|
|
|
(define eip (external-ip)) |
|
|
|
(define (screenshot) |
|
(define w (screen-w)) |
|
(define h (screen-h)) |
|
(define pix (make-u8vector (* w h 4))) |
|
(ss! pix w h) |
|
(values pix w h)) |
|
|
|
(receive (screenshot)) |
|
|
|
(nat-port-map (number->string serverport) |
|
(number->string externalport)) |
|
|
|
;; print cmd.exe's beutiful charset table: |
|
;; (let loop ((n 255)) |
|
;; (p n " " (integer->char n) "\t") |
|
;; (when (> n 0) (loop (- n 1)))) |
|
|
|
(define å "\x86") |
|
(define ø "\x94") |
|
|
|
(p " |
|
|
|
Hei Alf! |
|
|
|
Dette programmet gj"ø"r skermbildet ditt tilgjengelig p"å" Internett |
|
for de gangene du trenger \"teknisk assistanse\". |
|
Hele skjermen din vises til de som g"å"r p"å" linken nedenfor, |
|
oppgi denne til en av oss! Avslutt ved "å" lukke dette vinduet. |
|
H"å"per det funker og lykke til! |
|
|
|
http://" eip ":" externalport "/alf.png |
|
|
|
") |
|
|
|
(define l (tcp-listen serverport)) |
|
|
|
(define (app ip op) |
|
|
|
(define requestline (read-line ip)) |
|
(p "<< " (cadr (receive (tcp-addresses ip))) " " |
|
(with-output-to-string (lambda () (write requestline))) " ") |
|
|
|
;; eat other headers |
|
(let loop ((line #f)) |
|
(unless (or (eof-object? line) |
|
(equal? line "")) |
|
;;(p " << " (with-output-to-string (lambda () (write line))) "\n") |
|
(loop (read-line ip)))) |
|
|
|
(if (irregex-search " /alf.png " requestline) |
|
(begin |
|
(p "200\n") |
|
(receive (pix w h) (screenshot) |
|
(define body |
|
(with-output-to-string |
|
(lambda () |
|
(write-png pix w h 4)))) |
|
(display (conc "HTTP/1.1 200 OK\r |
|
Server: chicken5 alfss klm\r |
|
Content-type: image/png\r |
|
Content-length: " (string-length body) "\r |
|
Connection: close\r |
|
\r |
|
") op) |
|
(display body op) |
|
(flush-output op))) |
|
(begin |
|
(p "404\n") |
|
(display (conc "HTTP/1.1 404 Not Found\r |
|
Server: chicken5 alfss klm\r |
|
Connection: close\r |
|
\r |
|
") op) |
|
(flush-output op)))) |
|
|
|
(define |
|
thread-server |
|
(thread-start! |
|
(lambda () |
|
(let loop () |
|
(receive (ip op) (tcp-accept l) |
|
(thread-start! |
|
(lambda () |
|
(handle-exceptions e (begin (pp e)) |
|
(app ip op)) |
|
(close-input-port ip) |
|
(close-output-port op)))) |
|
(loop))))) |
|
|
|
(let loop () |
|
(p "\r" " - ") (thread-sleep! 0.25) |
|
(p "\r" " \\ ") (thread-sleep! 0.25) |
|
(p "\r" " | ") (thread-sleep! 0.25) |
|
(p "\r" " / ") (thread-sleep! 0.25) |
|
(loop)) |