summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/.gitignore2
-rw-r--r--examples/Makefile.am9
-rw-r--r--examples/README3
-rw-r--r--examples/rpc/client.scm.in105
-rw-r--r--examples/rpc/server.scm.in71
5 files changed, 188 insertions, 2 deletions
diff --git a/examples/.gitignore b/examples/.gitignore
index 9dccecc..d6d9e9b 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -6,4 +6,6 @@ sssh.scm
ssshd.scm
echo/client.scm
echo/server.scm
+rpc/client.scm
+rpc/server.scm
Makefile.in
diff --git a/examples/Makefile.am b/examples/Makefile.am
index ed49ffa..0c79edc 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -21,12 +21,16 @@ EXTRA_DIST = \
ssshd.scm.in \
echo/server.scm.in \
echo/client.scm.in \
- rrepl.scm.in
+ rrepl.scm.in \
+ rpc/client.scm.in \
+ rpc/server.scm.in
examplesdir = $(pkgdatadir)/examples
examples_echodir = $(pkgdatadir)/examples/echo
+examples_rpcdir = $(pkgdatadir)/examples/rpc
dist_examples_DATA = README sssh.scm ssshd.scm rrepl.scm
dist_examples_echo_DATA = echo/server.scm echo/client.scm
+dist_examples_rpc_DATA = rpc/client.scm rpc/server.scm
substitute = sed -e 's,[@]GUILE[@],$(GUILE),g'
@@ -40,4 +44,5 @@ SUFFIXES = .in
CLEANFILES = \
sssh.scm ssshd.scm \
echo/server.scm echo/client.scm \
- rrepl.scm
+ rrepl.scm \
+ rpc/server.scm rpc/client.scm
diff --git a/examples/README b/examples/README
index 49e3242..6735ce3 100644
--- a/examples/README
+++ b/examples/README
@@ -40,3 +40,6 @@ Please find sources in =echo/= directory:
* RREPL
A demo program that allows to connect to a remote REPL (RREPL) server. Pass
=--help= (or =-h=) flag to the program to get usage information.
+* RPC over SSH
+ A demo RPC client program that uses an SSH tunnel to make an RPC call over a
+ secure connection. See =rpc/= directory.
diff --git a/examples/rpc/client.scm.in b/examples/rpc/client.scm.in
new file mode 100644
index 0000000..d48c3a0
--- /dev/null
+++ b/examples/rpc/client.scm.in
@@ -0,0 +1,105 @@
+#!@GUILE@ \
+-e main
+!#
+
+;;; client.scm -- An example of an RPC call over a SSH tunnel.
+
+;; Copyright (C) 2015 Artyom V. Poptsov <poptsov.artyom@gmail.com>
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <http://www.gnu.org/licenses/>.
+
+
+;;; Commentary:
+
+;; A demo program that makes an RPC call over a SSH tunnel. For simplicity
+;; the program uses ssh-agent for authentication.
+;;
+;; The basic code for the RPC call is taken from Guile-RPC documentation.
+
+
+;;; Code:
+
+(use-modules (ice-9 getopt-long)
+ ;; RPC
+ (rpc rpc)
+ (rpc xdr)
+ (rpc xdr types)
+ ;; Guile-SSH
+ (ssh session)
+ (ssh auth)
+ (ssh tunnel))
+
+(define result-type
+ (make-xdr-struct-type (list xdr-integer ;; `integer_part'
+ xdr-unsigned-integer))) ;; `decimal_part'
+
+(define invoke-split-number
+ (make-synchronous-rpc-call 80000 0 ;; program and version
+ 1 ;; procedure number
+ xdr-double ;; argument type
+ result-type))
+
+(define (print-help-and-exit)
+ "Print information about program usage."
+ (display "\
+Usage: rrepl.scm [options] <host>
+
+Connect to a remote REPL (RREPL) using an ssh-agent for authentication.
+
+Options:
+ --user, -u <user> User name.
+ --port, -p <port> SSH port number (default: 22)
+ --help, -h Print this message and exit.
+")
+ (exit))
+
+(define (main args)
+ "Entry point of the program."
+ (let* ((options-spec '((user (single-char #\u) (value #t))
+ (port (single-char #\p) (value #t))
+ (help (single-char #\h) (value #f))))
+ (options (getopt-long args options-spec))
+ (user (option-ref options 'user (getenv "USER")))
+ (port (option-ref options 'port "22"))
+ (help-needed? (option-ref options 'help #f))
+ (args (option-ref options '() #f)))
+
+ (and (or help-needed?
+ (not args)
+ (null? args))
+ (print-help-and-exit))
+
+ ;; Make a new SSH session, connect it and authenticate the user.
+ (let* ((host (car args))
+ (session (make-session #:user user
+ #:host host
+ #:port (string->number port)
+ #:log-verbosity 'nolog)))
+ (connect! session)
+ (userauth-agent! session)
+ ;; Make a new SSH tunnel.
+ (let ((tunnel (make-tunnel session
+ #:port 12345
+ ;; Guile-RPC server listens on localhost.
+ #:host "127.0.0.1" ;
+ ;; Guile-RPC server port.
+ #:host-port 6666)))
+ ;; Make an RPC call using the SSH tunnel.
+ (call-with-ssh-forward tunnel
+ (lambda (socket)
+ (display (invoke-split-number 3.14 #x7777 socket))
+ (newline)))))))
+
+;;; client.scm ends here.
diff --git a/examples/rpc/server.scm.in b/examples/rpc/server.scm.in
new file mode 100644
index 0000000..6652300
--- /dev/null
+++ b/examples/rpc/server.scm.in
@@ -0,0 +1,71 @@
+#!@GUILE@ \
+-e main
+!#
+
+;;; server.scm -- An simple RPC server.
+
+;; Copyright (C) 2015 Artyom V. Poptsov <poptsov.artyom@gmail.com>
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <http://www.gnu.org/licenses/>.
+
+
+;;; Commentary:
+
+;; A simple RPC server.
+;;
+;; The code for the server is taken from Guile-RPC documentation.
+
+
+;;; Code:
+
+
+;; Taken from Guile-RPC examples.
+
+(use-modules (rpc rpc server)
+ (rpc xdr)
+ (rpc xdr types))
+
+(define (split-number-handler number)
+ ;; Handle a `split-number' request.
+ (let* ((int (floor number))
+ (dec (floor (* 1000 (- number int)))))
+ (list (inexact->exact int)
+ (inexact->exact dec))))
+
+(define result-type
+ (make-xdr-struct-type (list xdr-integer ;; `integer_part'
+ xdr-unsigned-integer))) ;; `decimal_part'
+
+(define my-rpc-program
+ ;; Define our RPC program.
+ (let* ((proc (make-rpc-procedure 1 xdr-double result-type
+ split-number-handler))
+ (version (make-rpc-program-version 0 (list proc))))
+ (make-rpc-program 80000 (list version))))
+
+(define (main args)
+ "Entry point of the program."
+ (let ((server-socket (socket PF_INET SOCK_STREAM 0)))
+ (bind server-socket AF_INET INADDR_LOOPBACK 6666)
+ (listen server-socket 1024)
+
+ ;; Go ahead and serve requests.
+ (run-stream-rpc-server (list (cons server-socket my-rpc-program))
+ 1000000 ;; a one-second timeout
+ #f ;; we don't care about closed connections
+ (lambda () ;; our idle thunk
+ (format #t "one second passed~%")))))
+
+;;; server.scm ends here.