source: project/release/3/remote-repl/trunk/remote-repl.html @ 11661

Last change on this file since 11661 was 11661, checked in by elf, 12 years ago

html file, why not.

File size: 21.6 KB
Line 
1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2<!-- Generated by eggdoc Revision: 1.20  -->
3<html>
4<head>
5<title>Eggs Unlimited - remote-repl</title><style type="text/css"> <!--
6      CODE {
7            color: #666666;
8          }
9/*   DT.definition EM { font-weight: bold; font-style: normal; } */
10
11     DT.definition { 
12                   background: #eee;
13                   color: black;
14                   padding: 0.2em 1em 0.2em 0.7em;
15                   margin-left: 0.2em;
16border: 1px solid #bbc;
17                   font-family: "Andale Mono", monospace;
18                   /* font-size: 1.2em; */
19                   
20                 }
21     DD {
22                   margin-top: 0.8em;
23                   margin-bottom: 0.8em;
24     }
25     DIV.subsection {
26                    border-top: 1px solid #448;
27                    padding-left: 1em;
28                    margin-bottom: 1.2em;
29     }
30     DIV.subsubsection {
31                    border-top: 1px dotted #99c;
32                    /* border-left: 1px solid #99c; */
33                    padding-left: 1em;
34                    margin-bottom: 1.2em;
35     }
36     DIV.subsubsubsection {
37                    border-top: 1px solid #ddf;
38                    padding-left: 1em;
39                    margin-bottom: 1.2em;
40     }
41
42         DIV.section {
43                 margin-bottom: 1.5em;
44         }
45         a:link {
46                 color: #336;
47         }
48         a:visited { color: #666; }
49         a:active  { color: #966; }
50         a:hover   { color: #669; }
51         body { margin: 0; padding: 0; background: #fff; color: #000; font: 9pt "Lucida Grande", "Verdana", sans-serif; }
52         H2 {
53                 background: #336;
54                 color: #fff;
55                 padding-top: 0.5em;
56                 padding-bottom: 0.5em;
57                 padding-left: 16px;
58                 margin: 0 0 1em 0;
59        }
60        UL LI {
61                list-style: none;
62        }
63        TT {
64                font-family: "Andale Mono", monospace;
65                /* font-size: 1.2em; */
66        }
67        H3 {
68                color: #113;
69                margin-bottom: 0.5em;
70        }
71        H4, H5, H6 {
72                color: #113;
73                margin-bottom: 1.0em;
74        }
75        H5 {
76                font-weight: normal;
77                font-style: italic;
78                font-size: 100%;
79                margin-top: 1.2em;
80        }
81        H6 {
82                font-weight: bold;
83                font-size: 85%;
84                margin-top: 1.2em;
85        }
86     DIV#eggheader {
87         text-align: center;
88                 float: right;
89                 margin-right: 2em;
90     }
91     DIV#header IMG {
92            /* display: block; margin-left: auto; margin-right: auto;  */
93            /* float: right; */
94            border: none;  /* firefox */
95     }
96     DIV#footer {
97                background: #bbd;
98                padding: 0.7em ;
99                border-top: 1px solid #cce;
100     }
101     DIV#footer hr {
102                display: none;
103     }
104     DIV#footer a {
105                float: left;
106     }
107     DIV#revision-history {
108         float: right;
109     }
110     
111     DIV#body {
112                 margin: 1em 1em 1em 16px;
113         }
114
115     DIV#examples PRE {
116       background: #eef;
117       padding: 0.1em;
118       border: 1px solid #aac;
119     }
120     PRE#license, DIV#examples PRE {
121       padding: 0.5em;
122     }
123     DIV#examples PRE {
124       /* font-size: 85%; */
125     }
126     PRE { font-family: "Andale Mono", monospace; }
127     TABLE {
128       background: #eef;
129       padding: 0.2em;
130       border: 1px solid #aac;
131       border-collapse: collapse;
132       width: 100%;
133     }
134     TABLE.symbol-table TD.symbol {
135          width: 15em;
136          font-family: "Andale Mono", monospace;
137          /* font-size: 1.2em; */
138     }
139     TH {
140       text-align: left;
141       border-bottom: 1px solid #aac;
142       padding: 0.25em 0.5em 0.25em 0.5em;
143     } 
144     TD { padding: 0.25em 0.5em 0.25em 0.5em; }
145     --></style></head>
146<body>
147<div id="header">
148<h2>remote-repl</h2>
149<div id="eggheader"><a href="index.html">
150<img src="egg.jpg" alt="[Picture of an egg]" /></a></div></div>
151<div id="body">
152<div class="section">
153<h3>Description</h3>remote read-eval-print loop client and server</div>
154<div class="section">
155<h3>Author</h3><a href="mailto:elf@ephemeral.net">elf</a></div>
156<div class="section">
157<h3>Version</h3>
158<ul>
159<li>1.0 20080816 [elf]  Initial release.</li>
160<li>1.1 20080816 [elf]  Bumped version to 1.1 from numerous small fixes. (mostly reported by certainty)</li></ul></div>
161<div class="section">
162<h3>Usage</h3><tt>(require-extension remote-repl)</tt></div>
163<div class="section">
164<h3>Download</h3><a href="remote-repl.egg">remote-repl.egg</a></div>
165<div class="section">
166<h3>Documentation</h3>
167<p>This extension provides a safe, portable, very flexible remote REPL facility.  The server component is fully threaded and may be plugged into any existing codebase without modification.  The client component is not threaded.</p>
168<p>For maximum flexibility, <u>all</u> procedures involved in the operation of these extensions may be specified.  The default is to use the tcp extension with no authentication and no sandboxing, but the design should make it easy to extend (e.g. through SSL sockets, ACL authentication, shared or unshared environments, etc) while maintaining safety.  All conditions are caught and handled properly, and no knowledge of threading, exception handling, or chicken internals is required.  Just plug it in and go!</p>
169<div class="subsection">
170<h4>Server Procedures</h4>
171<p>For the server component, use: <tt>(require-extension remote-repl-server)</tt></p>
172<dl>
173<dt class="definition"><strong>procedure:</strong> (rrepl-server-start PORTNUM [KEYARGS...])</dt>
174<dd>
175<p>Creates a new remote-repl server and returns a <tt>rrepl-server</tt> object.  The server automatically starts a listener thread, waiting for connections on <tt>PORTNUM</tt><tt>KEYARGS</tt> are optional keyword arguments for extending/tuning the server's behaviour, as given below:</p>
176<table style="table-layout: auto">
177<tr style="vertical-align: baseline">
178<th style="padding-top: 2.5em">Keyword</th>
179<th style="padding-top: 2.5em">Default</th>
180<th style="padding-top: 2.5em">Description</th></tr>
181<tr style="vertical-align: baseline">
182<td style="padding-top: 2em"><tt>listen</tt></td>
183<td style="padding-top: 2em"><tt>tcp-listen</tt></td>
184<td style="padding-top: 2em">
185<p>Procedure to create a listener for incoming connections.  Must take three arguments: an integer portnum on which to listen, an integer count of maximum pending connections, and a string (or <tt>#f</tt>) corresponding to a hostname/IP.  The final string argument, if given, is the only host from which connections are allowed.</p></td></tr>
186<tr style="vertical-align: baseline">
187<td style="padding-top: 2em"><tt>accept</tt></td>
188<td style="padding-top: 2em"><tt>tcp-accept</tt></td>
189<td style="padding-top: 2em">
190<p>Procedure to accept an incoming connection from a listener port.  Takes in a listener argument and returns an input port and an output port for the new connection.</p></td></tr>
191<tr style="vertical-align: baseline">
192<td style="padding-top: 2em"><tt>clisten</tt></td>
193<td style="padding-top: 2em"><tt>tcp-close</tt></td>
194<td style="padding-top: 2em">
195<p>Procedure to close and release a listener port given as an argument.</p></td></tr>
196<tr style="vertical-align: baseline">
197<td style="padding-top: 2em"><tt>auth</tt></td>
198<td style="padding-top: 2em"><tt>identity</tt></td>
199<td style="padding-top: 2em">
200<p>After accepting a connection with <tt>accept</tt>, the <tt>auth</tt> procedure is evaluated on the server object and the new session object created from the ports.  If the session authenticates, it is returned; if it does not pass, return <tt>#f</tt>.  The REPL thread for a session is not started until after authentication.</p></td></tr>
201<tr style="vertical-align: baseline">
202<td style="padding-top: 2em"><tt>host</tt></td>
203<td style="padding-top: 2em"><tt>#f</tt></td>
204<td style="padding-top: 2em">
205<p>If given, only accept connections originating from this hostname/IP.  See <tt>listen</tt> for more details.</p></td></tr>
206<tr style="vertical-align: baseline">
207<td style="padding-top: 2em"><tt>backlog</tt></td>
208<td style="padding-top: 2em"><tt>4</tt></td>
209<td style="padding-top: 2em">
210<p>Maximum number of pending connections.  See <tt>listen</tt> for more details.</p></td></tr>
211<tr style="vertical-align: baseline">
212<td style="padding-top: 2em"><tt>timeout-read</tt></td>
213<td style="padding-top: 2em"><tt>50000</tt></td>
214<td style="padding-top: 2em">
215<p>Timeout in milliseconds before aborting a read operation.  NOTE: DO NOT SET THIS TO <tt>#f</tt>!  Timeouts are handled gracefully and will not generate errors, and are required for proper operation.</p></td></tr>
216<tr style="vertical-align: baseline">
217<td style="padding-top: 2em"><tt>timeout-write</tt></td>
218<td style="padding-top: 2em"><tt>50000</tt></td>
219<td style="padding-top: 2em">
220<p>Timeout in milliseconds before aborting a write operation.  NOTE: DO NOT SET THIS TO <tt>#f</tt>!  Timeouts are handled gracefully and will not generate errors, and are required for proper operation.</p></td></tr>
221<tr style="vertical-align: baseline">
222<td style="padding-top: 2em"><tt>timeout-accept</tt></td>
223<td style="padding-top: 2em"><tt>50000</tt></td>
224<td style="padding-top: 2em">
225<p>Timeout in milliseconds before aborting an accept operation.  NOTE: DO NOT SET THIS TO <tt>#f</tt>!  Timeouts are handled gracefully and will not generate errors, and are required for proper operation.</p></td></tr>
226<tr style="vertical-align: baseline">
227<td style="padding-top: 2em"><tt>reader</tt></td>
228<td style="padding-top: 2em"><tt>read</tt></td>
229<td style="padding-top: 2em">
230<p>Procedure to read from a session's input port.</p></td></tr>
231<tr style="vertical-align: baseline">
232<td style="padding-top: 2em"><tt>evaler</tt></td>
233<td style="padding-top: 2em"><tt>eval</tt></td>
234<td style="padding-top: 2em">
235<p>Procedure for evaluating input in a session.  Takes TWO arguments, the expression to evaluate and the session object.  This allows the <tt>rrepl-session:extra</tt> field to be used, if desired.</p></td></tr>
236<tr style="vertical-align: baseline">
237<td style="padding-top: 2em"><tt>printer</tt></td>
238<td style="padding-top: 2em"><tt>write + newline</tt></td>
239<td style="padding-top: 2em">
240<p>Procedure for displaying evaluated output to a session's output port.  Takes two arguments, the object to be written and the output port.  NOTE: A NEWLINE MUST BE ADDED BY THIS PROCEDURE FOLLOWING OUTPUT.</p></td></tr>
241<tr style="vertical-align: baseline">
242<td style="padding-top: 2em"><tt>close-in</tt></td>
243<td style="padding-top: 2em"><tt>close-input-port</tt></td>
244<td style="padding-top: 2em">
245<p>Procedure for closing a session's input port.</p></td></tr>
246<tr style="vertical-align: baseline">
247<td style="padding-top: 2em; padding-bottom: 2.5em"><tt>close-out</tt></td>
248<td style="padding-top: 2em; padding-bottom: 2.5em"><tt>close-output-port</tt></td>
249<td style="padding-top: 2em; padding-bottom: 2.5em">
250<p>Procedure for closing a session's output port.</p></td></tr></table></dd>
251<dt class="definition"><strong>procedure:</strong> (rrepl-server-close SERVER-OBJ)</dt>
252<dd>
253<p>Closes the remote-repl server specified by <tt>SERVER-OBJ</tt>.  This includes closing the listener port and all active sessions.</p></dd></dl>
254<div class="subsubsection">
255<h5>RREPL-SERVER Procedures</h5>
256<dl>
257<dt class="definition"><strong>procedure:</strong> (rrepl-server? OBJ)</dt>
258<dd>
259<p>Returns <tt>#t</tt> if <tt>OBJ</tt> is a <tt>rrepl-server</tt> object.</p></dd>
260<dt class="definition"><strong>procedure:</strong> (rrepl-server:close-listen SERVER-OBJ)</dt>
261<dd>
262<p>Returns the procedure for closing the listener port.  This is a wrapper around the procedure specified by the keyword <tt>clisten</tt> for condition safety and metadata cleanup.</p></dd>
263<dt class="definition"><strong>procedure:</strong> (rrepl-server:read SERVER-OBJ)</dt>
264<dd>
265<p>Returns the procedure for reading from a session's input port, as specified by the <tt>reader</tt> keyword.</p></dd>
266<dt class="definition"><strong>procedure:</strong> (rrepl-server:eval SERVER-OBJ)</dt>
267<dd>
268<p>Returns the procedure for evaluating input in a session, as specified by the <tt>evaler</tt> keyword.</p></dd>
269<dt class="definition"><strong>procedure:</strong> (rrepl-server:print SERVER-OBJ)</dt>
270<dd>
271<p>Returns the procedure for printing to a session's output port, as specified by the <tt>printer</tt> keyword.</p></dd>
272<dt class="definition"><strong>procedure:</strong> (rrepl-server:close SERVER-OBJ)</dt>
273<dd>
274<p>Returns a procedure that takes a <tt>rrepl-server</tt> object and a <tt>rrepl-session</tt> object, and shuts down the session, after closing the ports.  Uses the procedures specified by the <tt>close-in</tt> and <tt>close-out</tt> keywords.</p></dd>
275<dt class="definition"><strong>procedure:</strong> (rrepl-server:listener SERVER-OBJ)</dt>
276<dd>
277<p>Returns the listener port associated with <tt>SERVER-OBJ</tt>, or <tt>#f</tt> if not accepting connections.</p></dd>
278<dt class="definition"><strong>procedure:</strong> (rrepl-server:listen-thr SERVER-OBJ)</dt>
279<dd>
280<p>Returns <tt>SERVER-OBJ</tt>'s listener thread.</p></dd>
281<dt class="definition"><strong>procedure:</strong> (rrepl-server:remotes SERVER-OBJ)</dt>
282<dd>
283<p>Returns a list of currently active <tt>rrepl-session</tt> objects connected to <tt>SERVER-OBJ</tt>.</p></dd>
284<dt class="definition"><strong>procedure:</strong> (rrepl-server:accepting SERVER-OBJ)</dt>
285<dd>
286<p>Returns <tt>#t</tt> if <tt>SERVER-OBJ</tt> is accepting new connections, or <tt>#f</tt> otherwise.</p></dd>
287<dt class="definition"><strong>procedure:</strong> (rrepl-server:accepting! SERVER-OBJ BOOL)</dt>
288<dd>
289<p>Sets the accepting-new-connections state of <tt>SERVER-OBJ</tt> to <tt>BOOL</tt>.  This is intended for use in <tt>auth</tt> procedures to force the listener port to close after a certain number of connections.  Setting this to <tt>#f</tt> will irrevocably kill the listener port.</p></dd>
290<dt class="definition"><strong>procedure:</strong> (rrepl-server:active SERVER-OBJ)</dt>
291<dd>
292<p>Returns <tt>#t</tt> if <tt>SERVER-OBJ</tt> is currently active, or <tt>#f</tt> if it is closed.  Note: A server running with a closed listener port is explicitly allowed.</p></dd>
293<dt class="definition"><strong>procedure:</strong> (rrepl-server:active! SERVER-OBJ BOOL)</dt>
294<dd>
295<p>Sets the running state of <tt>SERVER-OBJ</tt> to <tt>BOOL</tt>.  This should generally never be used, as setting to <tt>#f</tt> will shut down the server without proper cleanup.</p></dd></dl></div>
296<div class="subsubsection">
297<h5>RREPL-SESSION Procedures</h5>
298<dl>
299<dt class="definition"><strong>procedure:</strong> (rrepl-session? OBJ)</dt>
300<dd>
301<p>Returns <tt>#t</tt> if <tt>OBJ</tt> is a <tt>rrepl-session</tt> object.</p></dd>
302<dt class="definition"><strong>procedure:</strong> (rrepl-session:inport SESSION-OBJ)</dt>
303<dd>
304<p>Returns the input socket port associated with <tt>SESSION-OBJ</tt>.</p></dd>
305<dt class="definition"><strong>procedure:</strong> (rrepl-session:outport SESSION-OBJ)</dt>
306<dd>
307<p>Returns the output socket port associated with <tt>SESSION-OBJ</tt>.</p></dd>
308<dt class="definition"><strong>procedure:</strong> (rrepl-session:thread SESSION-OBJ)</dt>
309<dd>
310<p>Returns <tt>SESSION-OBJ</tt>'s REPL thread.</p></dd>
311<dt class="definition"><strong>procedure:</strong> (rrepl-session:extra SESSION-OBJ)</dt>
312<dd>
313<p>Returns <tt>SESSION-OBJ</tt>'s &quot;extra&quot; object (initially <tt>#f</tt>).  This is an arbitrary user-settable object for augmenting any other functionality.</p></dd>
314<dt class="definition"><strong>procedure:</strong> (rrepl-session:extra! SESSION-OBJ OBJ)</dt>
315<dd>
316<p>Sets the &quot;extra&quot; object for <tt>SESSION-OBJ</tt> to <tt>OBJ</tt><tt>OBJ</tt> may be any object.</p></dd>
317<dt class="definition"><strong>procedure:</strong> (rrepl-session:active SESSION-OBJ)</dt>
318<dd>
319<p>Returns <tt>#t</tt> if session is open and active, or <tt>#f</tt> otherwise.</p></dd>
320<dt class="definition"><strong>procedure:</strong> (rrepl-session:active! SESSION-OBJECT BOOL)</dt>
321<dd>
322<p>Sets the running state of <tt>SESSION-OBJ</tt> to <tt>BOOL</tt>.  This should generally never be used, as setting to <tt>#f</tt> will end the session without proper cleanup.</p></dd></dl></div></div>
323<div class="subsection">
324<h4>Client Procedures</h4>
325<p>For the client component, use: <tt>(require-extension remote-repl-client)</tt></p>
326<dl>
327<dt class="definition"><strong>procedure:</strong> (rrepl-client-connect HOSTNAME PORTNUM [KEYARGS...])</dt>
328<dd>
329<p>Creates a new remote-repl client and returns a <tt>rrepl-client</tt> object.  The server automatically connects and authenticates to <tt>HOSTNAME</tt> on port <tt>PORTNUM</tt><tt>KEYARGS</tt> are optional keyword arguments for extending/tuning the client's behaviour, as given below:</p>
330<table style="table-layout: auto">
331<tr style="vertical-align: baseline">
332<th style="padding-top: 2.5em">Keyword</th>
333<th style="padding-top: 2.5em">Default</th>
334<th style="padding-top: 2.5em">Description</th></tr>
335<tr style="vertical-align: baseline">
336<td style="padding-top: 2em"><tt>connect</tt></td>
337<td style="padding-top: 2em"><tt>tcp-connect</tt></td>
338<td style="padding-top: 2em">
339<p>Procedure to create a socket connection to a remote host.  Must take the hostname and portnum as its arguments, and returns an input port and an output port.</p></td></tr>
340<tr style="vertical-align: baseline">
341<td style="padding-top: 2em"><tt>auth</tt></td>
342<td style="padding-top: 2em"><tt>identity</tt></td>
343<td style="padding-top: 2em">
344<p>After connecting with <tt>connect</tt>, the <tt>auth</tt> procedure is evaluated on a new <tt>rrepl-client</tt> object to perform any authentication steps before handing off to the user.  Returns the <tt>rrepl-client</tt> object on success, or <tt>#f</tt> on failure.</p></td></tr>
345<tr style="vertical-align: baseline">
346<td style="padding-top: 2em"><tt>reader</tt></td>
347<td style="padding-top: 2em"><tt>read-line</tt></td>
348<td style="padding-top: 2em">
349<p>Procedure to read the output (one line) from the remote REPL.</p></td></tr>
350<tr style="vertical-align: baseline">
351<td style="padding-top: 2em"><tt>printer</tt></td>
352<td style="padding-top: 2em"><tt>write + newline</tt></td>
353<td style="padding-top: 2em">
354<p>Procedure for sending expressions to the output port for evaluation by the remote REPL.  Takes two arguments, the expression to be run and the output port.  NOTE: A NEWLINE MUST BE ADDED BY THIS PROCEDURE FOLLOWING OUTPUT.</p></td></tr>
355<tr style="vertical-align: baseline">
356<td style="padding-top: 2em"><tt>close-in</tt></td>
357<td style="padding-top: 2em"><tt>close-input-port</tt></td>
358<td style="padding-top: 2em">
359<p>Procedure for closing a client's input port.</p></td></tr>
360<tr style="vertical-align: baseline">
361<td style="padding-top: 2em; padding-bottom: 2.5em"><tt>close-out</tt></td>
362<td style="padding-top: 2em; padding-bottom: 2.5em"><tt>close-output-port</tt></td>
363<td style="padding-top: 2em; padding-bottom: 2.5em">
364<p>Procedure for closing a client's output port.</p></td></tr></table></dd>
365<dt class="definition"><strong>procedure:</strong> (rrepl-client-send CLIENT-OBJ EXPRESSION)</dt>
366<dd>
367<p>Sends <tt>EXPRESSION</tt> to the remote REPL for evaluation, and returns the result as a string.</p></dd>
368<dt class="definition"><strong>procedure:</strong> (rrepl-client-close CLIENT-OBJ)</dt>
369<dd>
370<p>Closes the remote REPL client specified by <tt>CLIENT-OBJ</tt>.  This includes closing the ports and notifying the server that the session is over.</p></dd></dl>
371<div class="subsubsection">
372<h5>RREPL-CLIENT Procedures</h5>
373<dl>
374<dt class="definition"><strong>procedure:</strong> (rrepl-client? OBJ)</dt>
375<dd>
376<p>Returns <tt>#t</tt> if <tt>OBJ</tt> is a <tt>rrepl-client</tt> object.</p></dd>
377<dt class="definition"><strong>procedure:</strong> (rrepl-client:read CLIENT-OBJ)</dt>
378<dd>
379<p>Returns the procedure for reading from a client's input port, as specified by the <tt>reader</tt> keyword.</p></dd>
380<dt class="definition"><strong>procedure:</strong> (rrepl-client:print CLIENT-OBJ)</dt>
381<dd>
382<p>Returns the procedure for printing to a client's output port, as specified by the <tt>printer</tt> keyword.</p></dd>
383<dt class="definition"><strong>procedure:</strong> (rrepl-client:close CLIENT-OBJ)</dt>
384<dd>
385<p>Returns a procedure that takes a <tt>rrepl-client</tt> object, and shuts down the client, after closing the ports.  Uses the procedures specified by the <tt>close-in</tt> and <tt>close-out</tt> keywords.</p></dd>
386<dt class="definition"><strong>procedure:</strong> (rrepl-client:inport CLIENT-OBJ)</dt>
387<dd>
388<p>Returns the input socket port associated with <tt>CLIENT-OBJ</tt>.</p></dd>
389<dt class="definition"><strong>procedure:</strong> (rrepl-client:outport CLIENT-OBJ)</dt>
390<dd>
391<p>Returns the output socket port associated with <tt>CLIENT-OBJ</tt>.</p></dd>
392<dt class="definition"><strong>procedure:</strong> (rrepl-client:active CLIENT-OBJ)</dt>
393<dd>
394<p>Returns <tt>#t</tt> if client is connected and active, or <tt>#f</tt> otherwise.</p></dd></dl></div></div>
395<div class="subsection">
396<h4>Bugs</h4>
397<p>None known</p></div>
398<div class="subsection">
399<h4>Licence</h4>
400<pre>Copyright (C) 2007-2008, Lenny Frank.  All rights reserved.
401
402Permission is hereby granted, free of charge, to any person obtaining a
403copy of this software and associated documentation files (the Software),
404to deal in the Software without restriction, including without limitation
405the rights to use, copy, modify, merge, publish, distribute, sublicense,
406and/or sell copies of the Software, and to permit persons to whom the
407Software is furnished to do so, subject to the following conditions:
408
409The above copyright notice and this permission notice shall be included
410in all copies or substantial portions of the Software.
411
412THE SOFTWARE IS PROVIDED AS-IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
413IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
414FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
415THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
416OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
417ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
418OTHER DEALINGS IN THE SOFTWARE.
419
420</pre></div></div></div>
421<div id="footer">
422<hr /><a href="index.html">&lt; Egg index</a>
423<div id="revision-history">$Revision$ $Date$</div>&nbsp;</div></body></html>
Note: See TracBrowser for help on using the repository browser.