411 REFERENCE · Wikibooks
Introduction to newLISP/The Internet
Reference material by Wikibooks contributors. This retains its source identity and is not 411 news reporting.
The internet
HTTP and networking
Most networking tasks are possible with newLISP's networking functions:
base64-dec decode a string from BASE64 format
base64-enc encode a string to BASE64 format
delete-url delete a URL
get-url read a file or page from the web
net-accept accept a new incoming connection
net-close close a socket connection
net-connect connect to a remote host
net-error return the last error
net-eval evaluate expressions on multiple remote newLISP servers
net-interface define the default network interface
net-listen listen for connections to a local socket
net-local local IP and port number for a connection
net-lookup the name for an IP number
net-peek number of characters ready to read
net-peer remote IP and port for a net-connect
net-ping send a ping packet (ICMP echo request) to one or more addresses
net-receive read data on a socket connection
net-receive-from read a UDP datagram on an open connection
net-receive-udp read a UDP datagram on and closes connection
net-select check a socket or list of sockets for status
net-send send data on a socket connection
net-send-to send a UDP datagram on an open connection
net-send-udp send a UDP datagram and closes connection
net-service translate a service name to a port number
net-sessions return a list of currently open connections
post-url post info to a URL address
put-url upload a page to a URL address.
xml-error return last XML parse error
xml-parse parse an XML document
xml-type-tags show or modify XML type tags
With these networking functions you can build all kinds of network-capable applications. With functions like net-eval you can start newLISP as a daemon on a remote computer and then use on a local computer to send newLISP code across the network for evaluation.
Accessing web pages
Here's a very simple example using get-url. Given the URL of a web page, obtain the source and then use replace and its list-building ability to generate a list of all the JPEG images on that page:
(set 'the-source (get-url "http://www.apple.com"))
(replace {src="(http\S*?jpg)"} the-source (push $1 images-list -1) 0)
(println images-list)
("http://images.apple.com/home/2006/images/ipodhifititle20060228.jpg"
"http://images.apple.com/home/2006/images/ipodhifitag20060228.jpg"
"http://images.apple.com/home/2006/images/macminiwings20060228.jpg"
"http://images.apple.com/home/2006/images/macminicallouts20060228.jpg"
"http://images.apple.com/home/2006/images/ipodhifititle20060228.jpg"
"http://images.apple.com/home/2006/images/ipodhifitag20060228.jpg")
A simple HTML Form
The simplest search form is probably something like this.
(load "cgi.lsp")
(println (string "Content-type: text/html\r\n\r\n"
[text]<!doctype html>
<html>
<head>
<title>Title</title>
</head>
<body>
[/text]))
(set 'search-string (CGI:get "userinput"))
(println (format [text]
<form name="form" class="dialog" method="GET">
<fieldset>
<input type="text" value="search" name="userinput" >
<input type="submit" style="display:none"/>
</fieldset>
</form>[/text]))
(unless (nil? search-string)
(println " I couldn't be bothered to search for \"" search-string "\""))
(println [text]
</body>
</html>
[/text])
A simple IRC client
The following code implements a simple IRC (Internet Relay Chat) client, and it shows how the basic network functions can be used. The script logs in to the server using the given username, and joins the # newlisp channel. Then the script divides into two threads: the first thread displays any channel activity in a continuous loop, while the second thread waits for input at the console. The only communication between the two threads is through the shared connected flag.
(set 'server (net-connect "irc.freenode.net" 6667))
(net-send server "USER newlispnewb 0 * :XXXXXXX\r\n")
(net-send server "NICK newlispnewb \r\n")
(net-send server "JOIN #newlisp\r\n")
(until (find "366" buffer)
(net-receive server buffer 8192 "\n")
(print buffer))
(set 'connected (share))
(share connected true)
(fork
(while (share connected)
(cond
((net-select server "read" 1000) ; read the latest
(net-receive server buffer 8192 "\n")
; ANSI colouring: output in yellow then switch back
(print "\n\027[0;33m" buffer "\027[0;0m"))
((regex {^PING :(.*)\r\n} buffer) ; play ping-pong
(net-send server (append "PONG :" (string $1 ) "\r\n"))
(sleep 5000))
((net-error) ; error
(println "\n\027[0;34m" "UH-OH: " (net-error) "\027[0;0m")
(share connected nil)))
(sleep 1000)))
(while (share connected)
(sleep 1000)
(set 'message (read-line))
(cond
((starts-with message "/") ; a command?
(net-send server (append (rest message) "\r\n"))
(if
(net-select server "read" 1000)
(begin
(net-receive server buffer 8192 "\n")
(print "\n\027[0;35m" buffer "\027[0;0m"))))
((starts-with message "quit") ; quit
(share connected nil))
(true ; send input as message
(net-send server (append "PRIVMSG #newlisp :" message "\r\n")))))
(println "finished; closing server")
(close server)
(exit)