-PowerScheme is a collection of techniques and tools aimed at reducing the gap
-between shell scripting and Scheme. The overall goal is to promote Scheme in
-fields where shell scripts are usually the first choice without any loss of
-effectiveness and convenience.
+**eping** is a ([Chicken](http://www.call-cc.org)) Scheme implementation of the
+ICMP ping utility. Although it can be used like an average OS ping utility,
+**eping** is intended to be used programmatically (e.g. for gathering
+statistics, monitoring). It uses raw sockets hence a privileged account must be
-1. [Port chaining](#markdown-header-port-chaining)
-2. [About this software](#markdown-header-about-this-software)
+[procedure] (eping HOST #!key (mode 'probe)
+HOST can be either an IPv4 address or an hostname: "192.168.1.1",
+"example.com", and even 'example.com are all valid hosts.
+**eping** supports four modes of operation: *probe* (default), *stats*, *dot* and
+1. [Probe mode](#markdown-header-probe-mode)
+2. [Stats mode](#markdown-header-stats-mode)
+3. [Dot mode](#markdown-header-dot-mode)
+4. [Mtu mode](#markdown-header-mtu-mode)
+6. [About this software](#markdown-header-about-this-software)
* [Version history](#markdown-header-version-history)
-The strength of the shell as a scripting platform is based on the powerful
-concept of pipes. The effectiveness of composing commands in priceless. For
-example, let's say we want to display in lower-case only those files which has
-a capital letter in their name. We can easily obtain this result by issuing
+In this mode **eping** returns true or false if it considers an host alive or
+unreachable respectively. The default behavior is to consider an host alive as
+soon as an echo reply is received. If no reply is received in *count* attempts,
+the host is considered unreachable. If not specified, *count* is 5 by default
+in this mode. Probe mode is the default one so it can be omitted as parameter.
-$ ls | grep [A-Z] | tr [A-Z] [a-z]
-Unfortunately, the strength as a programming language ends here since the
-primary role of the shell is to be an interactive CLI rather than a programming
-language. It would be valuable if a real programming language were able to
-replicate the powerful pipeline paradigm. PowerScheme tries to prove that
-Scheme is perfectly apt for the goal.
+The aliveness criteria can be changed through the four parameters *recv-min*,
+*lost-max*, *cons-recv-min*, *cons-lost-max* (see "Parameters" section). As
+soon as one of these conditions is met **eping** returns the associated boolean
+value. If no condition is met in *count* attempts *#f* is returned.
-Previous attempts at that, namely [scsh](http://www.scsh.net), try to mimic
-shell syntax in Scheme. The end result, while effective, feels alien and
-unnatural in Scheme. PowerScheme is different in that it tries to respect
-Scheme nature and doesn't define an explicit pipe operator since it leverages
-Scheme's normal order of evaluation. In PowerScheme the previous shell pipe
+In non-quiet 'submode' an informative message is displayed.
-(tr "[A-Z]" "[a-z]" (grep "[A-Z]" (! "ls")))
+(eping "call-cc.org" quiet: #f)
-Let's start by noticing that the order in which the procedures are written is
-"inverted". While this might feel odd to a shell user, it's second nature to a
-Scheme programmer. The "output" of *ls* "feeds" the *grep* procedure whose
-"output" in turn feeds the *tr* procedure.
-At this point, while you might have an intuitive understanding of the code, you
-may wonder what exactly those **!**, **grep** and **cut** things are and what
-exactly their output is.
+The output message can be customized through the *msg1* and *msg2* parameters.
-Let's start with the **!** operator. As you might guess, it's basically a fork
-to start the ls command but where its output ends up? It is captured in a
-Scheme port and that port is exactly what is returned.
-**grep** and **tr** are Scheme implementation of the corresponding Unix
-commands. Those are easily replicated in Scheme thus PowerScheme embeds them to
-avoid an excessive usage of costly fork operations. Others tools embedded in
-PowerScheme (v1.0) are: **cat**, **cut**, **head**, **sed** and **tail**.
-All these commands have a common interface: they accept a port as input and
-return a newly generated one. Thus the previous scheme code produces a chained
+In stats mode **eping** returns a vector of statistics #(sent lost rtt-min
+rtt-avg rtt-max rtt-std). The rtt values are expressed in *ms*.
+(eping "call-cc.org" mode: 'stats)
+===> #(5 0 133 134.2 136 0.92)
-A read operation on *p1* triggers a read operation on *p2* which in turn
-generates a read operation on *p3*. Thus basically not much happens until you
-invoke a read operation on the resulting port. You can use the standard Scheme
-arsenal to operate on ports and some helpful commands complemented by
+The non-quiet submode output resembles a standard ping utility:
-For example, if you are interested to operate on the result on a line-by-line
-basis then *read-line* is your friend:
+(eping "call-cc.org" mode: 'stats quiet: #f)
+64 bytes from 184.108.40.206: icmp_seq=0 ttl=52 time=139ms
+64 bytes from 220.127.116.11: icmp_seq=1 ttl=52 time=227ms
+64 bytes from 18.104.22.168: icmp_seq=2 ttl=52 time=135ms
+64 bytes from 22.214.171.124: icmp_seq=3 ttl=52 time=170ms
+64 bytes from 126.96.36.199: icmp_seq=4 ttl=52 time=256ms
+--- call-cc.org ping statistics ---
+5 packets transmitted, 5 packets received, 0% packet loss
+round-trip min/avg/max/stddev = 135.0/185.4/256.0/48.26 ms
+Ctrl-\ (posix) / Ctrl-Break (mingw) can be used to print partial statistics
+without halting the process while Ctrl-C quits the ping process.
-(read-line (tr "[A-Z]" "[a-z]" (grep "[A-Z]" (! "ls"))))
+(eping "call-cc.org" mode: 'stats quiet: #f count: 0)
+Request timeout for icmp_seq=0
+64 bytes from 188.8.131.52: icmp_seq=1 ttl=52 time=299ms
+64 bytes from 184.108.40.206: icmp_seq=2 ttl=52 time=151ms
+64 bytes from 220.127.116.11: icmp_seq=3 ttl=52 time=288ms
+64 bytes from 18.104.22.168: icmp_seq=4 ttl=52 time=434ms
+64 bytes from 22.214.171.124: icmp_seq=5 ttl=52 time=668ms
+64 bytes from 126.96.36.199: icmp_seq=6 ttl=52 time=349ms
+--- call-cc.org ping statistics ---
+7 packets transmitted, 6 packets received, 14.28% packet loss
+round-trip min/avg/max/stddev = 151.0/364.83/668.0/159.63 ms
+64 bytes from 188.8.131.52: icmp_seq=7 ttl=52 time=705ms
+64 bytes from 184.108.40.206: icmp_seq=8 ttl=52 time=143ms
+64 bytes from 220.127.116.11: icmp_seq=9 ttl=52 time=142ms
+64 bytes from 18.104.22.168: icmp_seq=10 ttl=52 time=156ms
+64 bytes from 22.214.171.124: icmp_seq=11 ttl=52 time=202ms
+^C64 bytes from 126.96.36.199: icmp_seq=12 ttl=52 time=147ms
+--- call-cc.org ping statistics ---
+13 packets transmitted, 12 packets received, 7.69% packet loss
+round-trip min/avg/max/stddev = 142.0/307/705.0/192.55 ms
-while if you want all the lines in one shot (bundled in a Scheme list) then
-*read-lines* is the way to go:
+By default 5 packets are sent. The *count* option can be used to change this
+value (0 meaning continuos operation).
+In this mode **eping** returns a single character for each echo request:
+- [.] Echo reply received
+- [N] Network unreachable
+- [P] Protocol unreachable
+- [F] Packet too big and DF bit set
+- [A] Administratively filtered
+- [T] Time to live exceeded
+- [O] Network/Host unreachable for TOS
+- [U] Unreachable (generic error)
-(read-lines (tr "[A-Z]" "[a-z]" (grep "[A-Z]" (! "ls"))))
+(eping "call-cc.org" mode: 'dot quiet: #f timeout: 134 count: 20)
-On the other hand, if you are just interested in sending the result to the
-standard output then PowerScheme provides an handy shortcut:
+The *dotcols* parameter can be used to set the number of chars to be printed
+before a newline. The default behavior (0) inserts a newline only after the
+(eping "call-cc.org mode": 'dot quiet: #f timeout: 134 count: 20 dotcols: 5)
+In quiet 'submode' a string built from the generated characters is returned.
-(~>1 (tr "[A-Z]" "[a-z]" (grep "[A-Z]" (! "ls"))))
+(eping "call-cc.org" mode: 'dot count: 3)
-Similarly, convenient operators **~>** and **~>>** (append mode) are provided
-if you want to redirect the output to a file:
+In mtu mode **eping** attempts to discover the MTU (Maximum Transmission Unit)
+along the path. To speed up the process it is reccomended to lower the default
+1000*ms* echo requests inter-packet time (*interval* option).
-(~> "file.txt" (tr "[A-Z]" "[a-z]" (grep "[A-Z]" (! "ls"))))
-(~>> "file.txt" (tr "[A-Z]" "[a-z]" (grep "[A-Z]" (! "ls"))))
+(eping "call-cc.org" mode: 'mtu interval: 250)
+Lossy links may slow down or even prevent the convergence. The *count* option
+can be used to increase the number of attempts (default is 64). If the MTU
+can't be computed *#f* is returned.
+* **count** The number of echo requests to be sent. The default is 5 for modes
+ other than *mtu* and 64 for this mode. If set to 0 echo requests are sent
+ until a probe condition is met (probe mode), MTU is computed (mtu mode),
+ or SIGINT (Ctrl-C) is received (all modes).
+* **timeout** The amount of time in *ms* to let pass before considering an host
+ unreachable (default is 1000ms).
+* **interval** The interval in *ms* between echo requests (default is
+ 1000ms). This value can't be set lower than *timeout* (this rule is enforced
+ lowering *timeout* in case).
+* **ttl** / **tos** Respectively the Time To Live and TOS in the IP header.
+* **dont-fragment** Sets the Don't Fragment (DF) flag in the IP header.
+* **src-addr** Binds the ICMP socket to a specific IP address.
+* **size** The ICMP payload size.
+* **pattern** A string used to fill the payload (repeated if necessary).
+* **id** The Identifier field (0-65535). By default this value is generated
+ randomly for every invocation of the eping function.
+* **seq-start** The initial sequence of the echo requests (0 by default).
+* **recv-min** Minimum number of received replies before considering an host
+* **lost-max** Maximum number of missed replies before considering an host
+* **cons-recv-min** Minimum number of consecutive received replies before
+ considering an host alive.
+* **cons-lost-max** Maximum number of consecutive missed replies before
+ considering an host unreachable.
+* **msg1** The message displayed when an host is considered alive. The default
+ message is "%i is alive\n" where %i is expanded to the IP address of the
+ host. Similarly %h is expanded to the hostname.
+* **msg2** The message displayed when an host is considered unreachable. By
+ default is an empty string.
+* **dotcols** In *dot* mode the number of displayed chars before a newline is
+ inserted. By default (0) a newline is inserted only after the last displayed
+* **quiet** By default eping doesn't display anything unless this option is set
-The source code is hosted at
-[Bitbucket](https://bitbucket.org/miklam/powerscheme/). Feel free to send pull
-requests or open an issue there. Alternatively, send an e-mail to the
-[chicken-users](mailto:firstname.lastname@example.org) mailing list for information
+The source code is hosted at [Bitbucket](https://bitbucket.org/miklam/eping/).
+Feel free to send pull requests or open an issue there. Alternatively, send an
+e-mail to the [chicken-users](mailto:email@example.com) mailing list for
+information or requests.
-[Michele La Monaca](mailto:
+[Michele La Monaca](mailto:@lamonaca.net)
-Michele La Monaca (
+Michele La Monaca (@lamonaca.net)
Redistribution and use in source and binary forms, with or without
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.