Changeset 33912 in project


Ignore:
Timestamp:
03/31/17 07:00:31 (3 months ago)
Author:
zbigniew
Message:

wiki/socket: normalize defsig id/arg names for improved doc semantics

File:
1 edited

Legend:

Unmodified
Added
Removed
  • wiki/eggref/4/socket

    r31137 r33912  
    55'''socket''' provides an interface to the BSD socket API.  For a somewhat higher-level interface, see the [[/egg/tcp6|tcp6]] and [[/egg/udp6|udp6]] extensions.
    66
    7 == Overview
     7=== Overview
    88
    99This extension provides a comprehensive interface to BSD sockets,
     
    1818[[toc:]]
    1919
    20 == Socket interface
    21 
    22 === Socket creation
     20=== Socket interface
     21
     22==== Socket creation
    2323
    2424<record>socket</record><br>
     
    3131
    3232Socket objects.  You construct a socket using the {{socket}} procedure,
    33 passing an address family {{af/*}} constant for FAMILY (IPv4, IPv6) and a
    34 socket type {{sock/*}} constant for socket TYPE (TCP, UDP).  PROTOCOL
     33passing an address family {{af/*}} constant for {{family}} (IPv4, IPv6) and a
     34socket type {{sock/*}} constant for socket {{type}} (TCP, UDP).  {{protocol}}
    3535should almost always be zero, unless you are creating raw sockets; it is
    3636implicit in the socket type.  Sockets take up a file descriptor in the
     
    4040Accessors:
    4141
    42 ; {{fileno}} : The socket's file descriptor.
    43 ; {{family}} : The socket family, an integer constant.
    44 ; {{type}} : The socket type, an integer constant.
    45 ; {{protocol}} : The socket protocol, an integer constant.
     42; {{socket-fileno}} : The socket's file descriptor.
     43; {{socket-family}} : The socket family, an integer constant.
     44; {{socket-type}} : The socket type, an integer constant.
     45; {{socket-protocol}} : The socket protocol, an integer constant.
    4646
    4747Note that sockets are also implicitly created by {{socket-connect/ai}}
     
    8282Protocol constants for socket creation.
    8383
    84 === Socket addresses
     84==== Socket addresses
    8585
    8686<record>sockaddr</record><br>
     
    103103Socket address object accessors are:
    104104
    105 ; {{family}} : returns the socket address family as an integer constant, e.g. {{af/inet}}.
    106 ; {{address}} : returns the address of a socket as a string (for Internet sockets, this is the IP address).
    107 ; {{port}} : returns the socket port for Internet sockets; it is an error to call it on another type of socket.
    108 ; {{path}} : returns the pathname for UNIX sockets, or an error for other socket types.
    109 ; {{->string}} : returns a compact representation of the socket address as a string.  For Internet sockets, it returns "address" when port is 0; otherwise, it returns "address:port" for IPv4 addresses and "[address]:port" for IPv6 addresses.
     105; {{sockaddr-family}} : returns the socket address family as an integer constant, e.g. {{af/inet}}.
     106; {{sockaddr-address}} : returns the address of a socket as a string (for Internet sockets, this is the IP address).
     107; {{sockaddr-port}} : returns the socket port for Internet sockets; it is an error to call it on another type of socket.
     108; {{sockaddr-path}} : returns the pathname for UNIX sockets, or an error for other socket types.
     109; {{sockaddr->string}} : returns a compact representation of the socket address as a string.  For Internet sockets, it returns "address" when port is 0; otherwise, it returns "address:port" for IPv4 addresses and "[address]:port" for IPv6 addresses.
    110110
    111111<procedure>(inet-address addr port)</procedure>
    112112
    113 Returns a {{sockaddr}} object constructed from IP address ADDR (a
    114 string) and port PORT (a number or numeric string).  If the address
     113Returns a {{sockaddr}} object constructed from IP address {{addr}} (a
     114string) and port {{port}} (a number or numeric string).  If the address
    115115or port input is invalid, an error is raised.
    116116
    117 If ADDR is {{#f}}, the unspecified address is used ("::" or "0.0.0.0").
    118 If PORT is {{#f}}, the unspecified port is used (integer 0).
    119 It is an error for both ADDR and PORT to be unspecified.
     117If {{addr}} is {{#f}}, the unspecified address is used ("::" or "0.0.0.0").
     118If {{port}} is {{#f}}, the unspecified port is used (integer 0).
     119It is an error for both {{addr}} and {{port}} to be unspecified.
    120120
    121121Note that when IPv6 is preferred on your system, the unspecified
     
    125125"::" or "0.0.0.0" -- in lieu of {{#f}}.
    126126
    127 <procedure>(unix-address PATH)</procedure>
    128 
    129 Returns a {{sockaddr}} object constructed from the pathname PATH,
     127<procedure>(unix-address path)</procedure>
     128
     129Returns a {{sockaddr}} object constructed from the pathname {{path}},
    130130suitable for use with a socket in address family {{af/unix}}.
    131131Throws an error if UNIX sockets are not supported on your platform.
    132132
    133 === Address resolution
     133==== Address resolution
    134134
    135135<procedure>(address-information node service #!key family (type sock/stream) protocol flags)</procedure><br>
     
    143143such as {{socket-bind}} and {{socket-connect}}.
    144144
    145 NODE is either a node name (string) or IP address (string).
    146 SERVICE may be a string representing a service name or port number, or
    147 an integer.  If NODE is {{#f}}, it is treated as the loopback address;
     145{{node}} is either a node name (string) or IP address (string).
     146{{service}} may be a string representing a service name or port number, or
     147an integer.  If {{node}} is {{#f}}, it is treated as the loopback address;
    148148however, if {{ai/passive}} is set it is treated as the unspecified
    149 address.  If SERVICE is {{#f}}, it is treated as unspecified (0).
     149address.  If {{service}} is {{#f}}, it is treated as unspecified (0).
    150150
    151151Keyword arguments accept numeric constants and restrict the returned addresses accordingly:
    152152
    153 ; {{family:}} : Address family, either {{af/inet}} or {{af/inet6}}, defaulting to {{#f}}.  If {{#f}}, both IPv6 and IPv4 addresses may be returned, depending on your system's configuration and IP stack.
    154 ; {{type:}} : Socket type; usually {{sock/stream}} or {{sock/dgram}}, defaulting to {{sock/stream}}.  Can be {{#f}}, but results may vary between systems, so it is safer to specify one.  See examples.
    155 ; {{protocol:}} : Protocol type, usually {{#f}}.  Can also be {{ipproto/tcp}} or {{ipproto/udp}}; however, some systems (such as Windows) do not construct a proper socket address when {{type:}} is unspecified, so it is safer to just provide a value for {{type:}} and leave this as {{#f}}.
     153; {{family}} : Address family, either {{af/inet}} or {{af/inet6}}, defaulting to {{#f}}.  If {{#f}}, both IPv6 and IPv4 addresses may be returned, depending on your system's configuration and IP stack.
     154; {{type}} : Socket type; usually {{sock/stream}} or {{sock/dgram}}, defaulting to {{sock/stream}}.  Can be {{#f}}, but results may vary between systems, so it is safer to specify one.  See examples.
     155; {{protocol}} : Protocol type, usually {{#f}}.  Can also be {{ipproto/tcp}} or {{ipproto/udp}}; however, some systems (such as Windows) do not construct a proper socket address when {{type}} is unspecified, so it is safer to just provide a value for {{type}} and leave this as {{#f}}.
    156156
    157157The behavior of {{address-information}} can be influenced by the value
    158 of {{flags:}}, which should be the {{bitwise-ior}} (or simply {{+}}) of any
     158of {{flags}}, which should be the {{bitwise-ior}} (or simply {{+}}) of any
    159159of the following constants:
    160160
     
    209209Address information record returned by {{address-information}}.
    210210
    211 * {{address}} is the {{sockaddr}} socket address object;
    212 * {{family}}, {{socktype}} and {{protocol}} are numeric constants in the {{af/}}, {{sock/}} and {{ipproto/}} families respectively;
    213 * {{canonname}} is the canonical (FQDN) name of this host and is present only if the {{ai/canonname}} flag was used; otherwise {{#f}};
    214 * {{flags}} is the bitwise OR of {{ai/}} flags used when constructing this object.  The system may set certain flags itself so this is probably not reliably useful.
     211* {{addrinfo-address}} is the {{sockaddr}} socket address object;
     212* {{addrinfo-family}}, {{addrinfo-socktype}} and {{addrinfo-protocol}} are numeric constants in the {{af/}}, {{sock/}} and {{ipproto/}} families respectively;
     213* {{addrinfo-canonname}} is the canonical (FQDN) name of this host and is present only if the {{ai/canonname}} flag was used; otherwise {{#f}};
     214* {{addrinfo-flags}} is the bitwise OR of {{ai/}} flags used when constructing this object.  The system may set certain flags itself so this is probably not reliably useful.
    215215
    216216<procedure>(name-information saddr #!optional (flags 0))</procedure><br>
     
    221221<constant>ni/nofqdn</constant><br>
    222222
    223 Given a socket address object SADDR, performs a reverse-lookup to
     223Given a socket address object {{saddr}}, performs a reverse-lookup to
    224224obtain the node and service names, returning them as the pair
    225225{{("node" . "service")}}.  If hostname lookup fails, the numeric
     
    229229The socket address object is usually constructed with {{inet-address}}
    230230or obtained from a socket call, e.g. {{socket-peer-name}}.  As a
    231 convenience in socket 0.2.1 and later, if {{SADDR}} is a string, it is
    232 converted to a socket address object with {{(inet-address SADDR #f)}}.
     231convenience in socket 0.2.1 and later, if {{saddr}} is a string, it is
     232converted to a socket address object with {{(inet-address saddr #f)}}.
    233233
    234234The behavior of {{name-information}} can be influenced by FLAGS.  FLAGS
     
    265265   ; => ("taco.universe12.dim" . 31828)
    266266
    267 === Setup and teardown
     267==== Setup and teardown
    268268
    269269<procedure>(socket-connect so saddr)</procedure><br>
    270270<procedure>(socket-connect/ai ais)</procedure><br>
    271271
    272 {{socket-connect}} connects to the remote socket address SADDR over
    273 the socket SO.  Upon completion, SO will be connected; on connection
     272{{socket-connect}} connects to the remote socket address {{saddr}} over
     273the socket {{so}}.  Upon completion, {{so}} will be connected; on connection
    274274failure an error is thrown.  The return value is unspecified.  This is
    275275a non-blocking operation; other SRFI-18 threads can continue to run.
     
    284284
    285285{{socket-connect/ai}} connects to the addresses in the {{addrinfo}}
    286 list AIS sequentially until the connection succeeds or there are no
     286list {{ais}} sequentially until the connection succeeds or there are no
    287287more addresses.  If a fatal error occurs while connecting, it aborts
    288288immediately; but transient or timeout errors cause it to try the next
     
    321321<procedure>(socket-bind so saddr)</procedure>
    322322
    323 Binds socket SO to socket address SADDR.  The return value is unspecified.
     323Binds socket {{so}} to socket address {{saddr}}.  The return value is unspecified.
    324324
    325325 ; Bind to the IPv4 unspecified address on port 8000.
     
    340340<procedure>(socket-listen so backlog)</procedure>
    341341
    342 Listen for incoming connections on socket SO, with a connection queue
    343 of integer length BACKLOG.   This call is only valid for
     342Listen for incoming connections on socket {{so}}, with a connection queue
     343of integer length {{backlog}}.   This call is only valid for
    344344connection-oriented (stream) sockets.
    345345
     
    347347<procedure>(socket-accept-ready? so)</procedure>
    348348
    349 {{socket-accept}} accepts a connection on listening socket SO,
     349{{socket-accept}} accepts a connection on listening socket {{so}},
    350350returning a new connected {{socket}} object.  The address of the peer
    351351can be obtained by calling {{socket-peer-name}} on the socket.
     
    353353This is a non-blocking operation; other SRFI-18 threads can continue
    354354to run in the meantime, although this one will block.  If the accept
    355 does not complete within {{(socket-accept-timeout)}} milliseconds, a
     355does not complete within {{socket-accept-timeout}} milliseconds, a
    356356timeout error is raised.
    357357
     
    366366<constant>shut/rdwr</constant>
    367367
    368 Shutdown the full-duplex connection on socket SO in the manner of HOW:
     368Shutdown the full-duplex connection on socket {{so}} in the manner of {{how}}:
    369369
    370370; {{shut/rd}} : disallow further receiving
     
    379379<procedure>(socket-close so)</procedure>
    380380
    381 Close socket SO.  If a connection was established,
     381Close socket {{so}}.  If a connection was established,
    382382the socket is shut down gracefully.
    383383
     
    393393This might go away or change semantics in the future.
    394394
    395 === Status
     395==== Status
    396396
    397397<procedure>(socket-name so)</procedure>
    398398
    399399Return a {{sockaddr}} object representing the address of the local
    400 endpoint of socket SO.  If the socket has not been bound, it
     400endpoint of socket {{so}}.  If the socket has not been bound, it
    401401returns {{#f}}.
    402402
     
    407407
    408408Return a {{sockaddr}} object representing the address of the remote
    409 endpoint of socket SO.  If no connection exists, returns {{#f}}.  This
     409endpoint of socket {{so}}.  If no connection exists, returns {{#f}}.  This
    410410can be used after {{socket-connect}} or on a socket returned by
    411411{{socket-accept}}.  Note that this also works with UDP "connections"
     
    415415to describe a socket address. 
    416416
    417 === Data transfer
    418 
    419 ==== Receiving data
     417==== Data transfer
     418
     419===== Receiving data
    420420
    421421<procedure>(socket-receive! so buf #!optional (start 0) (end #f) (flags 0))</procedure>
    422422<procedure>(socket-receive-ready? so)</procedure>
    423423
    424 Receives data from socket SO and writes it into BUF, which may be a
    425 string or a blob.  START and END are optional offsets into BUF; the
    426 call attempts to read END - START = LEN bytes.  If END is {{#f}}, it
     424Receives data from socket {{so}} and writes it into {{buf}}, which may be a
     425string or a blob.  {{start}} and {{end}} are optional offsets into {{buf}}; the
     426call attempts to read {{end}} - {{start}} = {{len}} bytes.  If {{end}} is {{#f}}, it
    427427is interpreted as the end of the blob or string.
    428428
    429429This call will block until data is available, but other threads can
    430430proceed.  If the receive does not complete within
    431 {{(socket-receive-timeout)}} milliseconds, a timeout error is raised.
     431{{socket-receive-timeout}} milliseconds, a timeout error is raised.
    432432To avoid blocking the current thread, you can check if data is ready
    433433via {{socket-receive-ready?}}.
    434434
    435 Returns the number of bytes actually received (and updates BUF as
     435Returns the number of bytes actually received (and updates {{buf}} as
    436436a side effect).
    437437
    438 For datagram sockets, if LEN is smaller than the amount of data in
     438For datagram sockets, if {{len}} is smaller than the amount of data in
    439439the next datagram, the rest of the data is irrevocably lost.
    440440
    441441<procedure>(socket-receive so len #!optional (flags 0))</procedure>
    442442
    443 Receives up to LEN bytes from data from socket SO and returns it
     443Receives up to {{len}} bytes from data from socket {{so}} and returns it
    444444in a string (sized to fit the returned data).  Otherwise, it behaves
    445445like {{socket-receive!}}.
     
    453453<procedure>(socket-receive-from so len #!optional (flags 0))</procedure>
    454454
    455 Receives up to LEN bytes from data from socket SO and returns two
     455Receives up to {{len}} bytes from data from socket {{so}} and returns two
    456456values: a string (sized to fit the returned data), and a {{sockaddr}}
    457457object representing the source.  Otherwise, it behaves like
    458458{{socket-receive-from!}}.
    459459
    460 ==== Sending data
     460===== Sending data
    461461
    462462<procedure>(socket-send so buf #!optional (start 0) (end #f) (flags 0))</procedure>
    463463
    464 Sends data to socket SO from the buffer BUF, which may be a
    465 string or a blob.  START and END are optional offsets into BUF; the
    466 call attempts to write END - START = LEN bytes.  If END is {{#f}}, it
     464Sends data to socket {{so}} from the buffer {{buf}}, which may be a
     465string or a blob.  {{start}} and {{end}} are optional offsets into {{buf}}; the
     466call attempts to write {{end}} - {{start}} = {{len}} bytes.  If {{end}} is {{#f}}, it
    467467is interpreted as the end of the blob or string.
    468468
     
    476476
    477477Like {{socket-send}}, but sends data over a connectionless datagram
    478 socket to {{sockaddr}} SADDR, returning the number of bytes actually
     478socket to {{sockaddr}} {{saddr}}, returning the number of bytes actually
    479479sent.
    480480
    481481<procedure>(socket-send-all so buf #!optional (start 0) (end #f) (flags 0))</procedure>
    482482
    483 Sends all data between START and END in BUF over connected socket SO
     483Sends all data between {{start}} and {{end}} in {{buf}} over connected socket {{so}}
    484484by calling {{socket-send}} multiple times until all data is sent.
    485485
     
    491491buffer divided into, say, 512-byte datagrams.
    492492
    493 === I/O ports
     493==== I/O ports
    494494
    495495<procedure>(socket-i/o-ports so)</procedure>
    496496
    497497Constructs an input port I and an output port O associated with
    498 the connected socket SO, returning {{(values I O)}}.  This procedure
     498the connected socket {{so}}, returning {{(values I O)}}.  This procedure
    499499works on both stream and datagram sockets.
    500500
     
    556556   ...)
    557557
    558 <procedure>(socket-i/o-port->socket p)</procedure>
    559 
    560 Returns the socket object assocated with input or output port P.  From
     558<procedure>(socket-i/o-port->socket port)</procedure>
     559
     560Returns the socket object assocated with input or output port {{port}}.  From
    561561there you can obtain a file descriptor with {{socket-fileno}}.
    562562
     
    564564supported to obtain a file descriptor.  (Also see [[#Bugs and limitations]].)
    565565
    566 <procedure>(socket-abandon-port p)</procedure>
    567 
    568 Marks the socket input or output port P as abandoned.  Normally, when
     566<procedure>(socket-abandon-port port)</procedure>
     567
     568Marks the socket input or output port {{port}} as abandoned.  Normally, when
    569569an socket input port is closed the read side of the connection is shut
    570570down; similarly closing the output port shuts down the write side.
     
    575575their abandoned status.
    576576
    577 === Parameters
     577==== Parameters
    578578
    579579<parameter>(socket-connect-timeout ms) [default: #f]</parameter><br>
     
    609609Input buffering can not be disabled.
    610610
    611 == Socket option interface
     611=== Socket option interface
    612612
    613613BSD socket option values are of substantially differing types: boolean flags
     
    635635socket type or option value).
    636636
    637 === Socket option accessors
     637==== Socket option accessors
    638638
    639639Below is a list of option procedures and their value type.  The procedure names are
     
    659659<procedure>(so-type s)                [so/type]       (r/o)</procedure><br>
    660660
    661 Getters / setters for boolean and integer socket-level options, where S is a
     661Getters / setters for boolean and integer socket-level options, where {{s}} is a
    662662''socket'' object or an integer file descriptor.  To set an option, use SRFI-17
    663663generalized set:
     
    680680<procedure>(tcp-max-segment-size s) [tcp/maxseg]</procedure><br>
    681681
    682 Getters / setters for TCP-level socket options ({{ipproto/tcp}}).  S is
     682Getters / setters for TCP-level socket options ({{ipproto/tcp}}).  {{s}} is
    683683a ''socket'' object or an integer file descriptor.
    684684
     
    687687<procedure>(ip-time-to-live s)      [ip/ttl]</procedure><br>
    688688
    689 Getters / setters for IP-level socket options ({{ipproto/ip}}).  S is
     689Getters / setters for IP-level socket options ({{ipproto/ip}}).  {{s}} is
    690690a ''socket'' object or an integer file descriptor.
    691691
    692692<procedure>(ipv6-v6-only? s)        [ipv6/v6only]            </procedure><br>
    693693
    694 Getters / setters for IPv6-level socket options ({{ipproto/ipv6}}).  S is
     694Getters / setters for IPv6-level socket options ({{ipproto/ipv6}}).  {{s}} is
    695695a ''socket'' object or an integer file descriptor.
    696696
    697 === Low-level socket option interface
     697==== Low-level socket option interface
    698698
    699699A low-level socket option interface is also provided.  This is
     
    707707<procedure>(set-socket-option s level name val)</procedure>
    708708
    709 Set the value of option {{NAME}} at socket level {{LEVEL}} on socket {{S}} to {{VAL}}.
    710 {{VAL}} may be a fixnum or a boolean.  It may also be a blob or a string; if so, the raw
     709Set the value of option {{name}} at socket level {{level}} on socket {{s}} to {{val}}.
     710{{val}} may be a fixnum or a boolean.  It may also be a blob or a string; if so, the raw
    711711contents are passed to the option, which is useful when a structure is required.  The return value is unspecified.
    712712
     
    725725<procedure>(get-socket-option s level name #!optional (len #f))</procedure>
    726726
    727 Get the value of option {{NAME}} at socket level {{LEVEL}} on socket
    728 {{S}}.  If {{LEN}} is {{#f}}, the default, we interpret the option
     727Get the value of option {{name}} at socket level {{level}} on socket
     728{{s}}.  If {{len}} is {{#f}}, the default, we interpret the option
    729729value as an integer and return that.  Otherwise, temporary storage of
    730 length {{LEN}} is allocated to receive the binary option data; after
    731 the call it is resized to fit the data, and returned.  If LEN is too
     730length {{len}} is allocated to receive the binary option data; after
     731the call it is resized to fit the data, and returned.  If {{len}} is too
    732732small to hold the returned data, the result is undefined.
    733733
     
    745745 (get-socket-option S ipproto/tcp tcp/nodelay 4)   ; => #${08000000}
    746746
    747 === Socket option constants
     747==== Socket option constants
    748748
    749749Integer constants are provided for socket levels, socket types, and
     
    759759it.
    760760
    761 ==== Socket-level constants
     761===== Socket-level constants
    762762
    763763<constant>so/reuseaddr</constant><br>
     
    785785{{get-socket-option}} at level {{sol/socket}}.
    786786
    787 ==== TCP-level constants
     787===== TCP-level constants
    788788
    789789<constant>tcp/nodelay</constant><br>
     
    796796{{get-socket-option}} at level {{ipproto/tcp}}.
    797797
    798 ==== IP-level constants
     798===== IP-level constants
    799799
    800800<constant>ip/options</constant><br>
     
    822822{{get-socket-option}} at level {{ipproto/ip}}.
    823823
    824 ==== Socket and protocol levels
     824===== Socket and protocol levels
    825825
    826826<constant>sol/socket</constant><br>
     
    833833Socket level constants, for use with {{set-socket-option}} and {{get-socket-option}}.
    834834
    835 === SO_LINGER lowlevel example
     835==== SO_LINGER lowlevel example
    836836
    837837This is a pretty hairy example of getting and setting the {{so/linger}} option, which does
     
    865865    ; => (#t 100)
    866866
    867 == Examples
    868 
    869 === Client-server examples
     867=== Examples
     868
     869==== Client-server examples
    870870
    871871For a simple example of client-server communication over a unix socket, see
     
    874874A TCP/IP example is still to be written.
    875875
    876 === Disable Nagle's Algorithm on TCP listener socket
     876==== Disable Nagle's Algorithm on TCP listener socket
    877877
    878878The [[/man/4/Unit tcp|tcp unit]] does not support setting arbitrary socket
     
    884884 (set! (tcp-no-delay? S) #t)
    885885
    886 === Set socket options on HTTP server
     886==== Set socket options on HTTP server
    887887
    888888This is similar to the above.  HTTP servers may see some performance
     
    899899   ((http:make-server ...)))
    900900
    901 == Bugs and limitations
     901=== Bugs and limitations
    902902
    903903* If IPv6 support is totally unavailable on your platform (not simply disabled)
     
    914914  used with core tcp ports.
    915915
    916 == About this egg
    917 
    918 === Author
     916=== About this egg
     917
     918==== Author
    919919
    920920[[http://3e8.org|Jim Ursetto]]
     
    923923unit by Felix Winkelmann and the rest of the Chicken team.
    924924
    925 === Version history
     925==== Version history
    926926
    927927; 0.2.6 : Handle {{##sys#scan-buffer-line}} signature change in CHICKEN 4.8.2.  Bug reported by Jonathan Chan and David Krentzlin.
     
    934934; 0.1 : Initial release for Chicken 4.
    935935
    936 === Portability
     936==== Portability
    937937
    938938* socket 0.1 has been successfully built and tested on Mac OS X 10.5,
    939939  Ubuntu 10.10, Windows XP SP3 and NetBSD 5.1.
    940940
    941 === License
    942 
    943  Copyright (c) 2011-2014, Jim Ursetto.  All rights reserved.
     941==== License
     942
     943 Copyright (c) 2011-2017, Jim Ursetto.  All rights reserved.
    944944 Copyright (c) 2008-2011, The Chicken Team
    945945 Copyright (c) 2000-2007, Felix L. Winkelmann
Note: See TracChangeset for help on using the changeset viewer.